OmniAICreator/Qiita-1.07M huggingface dataset:
FastAPI docker tutorial 


FastAPIの下記のページを参考にDockerでFastAPIを使用する。公式ページ記載の手順だと、main.pyを変更したときに、変更分が反映されなかったため、少し改修したときのメモ。  
https://fastapi.tiangolo.com/ja/deployment/docker/
# 環境
- Windows11
- PowerShell

# フォルダやファイルの作成
下記の構成となるようにフォルダやファイルを作成する。
![スクリーンショット 2024-01-29 145152.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1319419/63a3583a-21be-e0cb-6b2d-23fb5451ebf8.png)


main.py, requirements.txtは公式のページに書いてある通りに作成した。Dockerfileのみ下記の点を変更した。
- main.pyを修正したときに変更分が反映されるように、uvicornコマンドに"--reload"オプションを追加した。
- ポートを8000に変更した。

```main.py
from typing import Union

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
    return {"item_id": item_id, "q": q}
```

```requirements.txt
fastapi>=0.68.0,<0.69.0
pydantic>=1.8.0,<2.0.0
uvicorn>=0.15.0,<0.16.0
```

```Dockerfile
# 
FROM python:3.9

# 
WORKDIR /code

# 
COPY ./requirements.txt /code/requirements.txt

# 
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt

# 
COPY ./app /code/app

# 
CMD ["uvicorn", "app.main:app", "--reload", "--host", "0.0.0.0", "--port", "8000"]
```

# dockerコンテナ作成
tutorialのフォルダでターミナルを開いて下記のコマンドを実行し、docker imageを作成する。
```
docker build -t fastapi-tutorial .
```
imageが作成されていることを確認する。
```
docker imaegs
```
```
REPOSITORY                TAG       IMAGE ID       CREATED         SIZE
fastapi-tutorial          latest    f5b786946733   2 minutes ago   1.02GB
```
docker containerを作成＆起動する。port 8000をマウントする。ホストのappフォルダとコンテナの/code/appフォルダをマウントする。
```
docker run -d --name fastapi-tutorial -p 8000:8000 -v .\app:/code/app fastapi-tutorial
```
docker containerが作成&起動していることを確認する。
```
docker ps
```
```
CONTAINER ID   IMAGE                 COMMAND                   CREATED         STATUS         PORTS                    NAMES
7cca4392c817   fastapi-tutorial      "uvicorn app.main:ap…"   2 minutes ago   Up 2 minutes   0.0.0.0:8000->8000/tcp   fastapi-tutorial
```

# GETリクエスト
Google Chromeで、http://localhost:8000
を開く。
ブラウザにHello Worldが表示される。
![スクリーンショット 2024-01-29 154937.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1319419/fd9be9da-6e9d-18a3-539d-1bee5fcb5008.png)



http://localhost:8000/items/5?q=query
を開く。
![スクリーンショット 2024-01-29 155001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1319419/751dfc50-7a11-6c14-7ccf-9c5931020df1.png)


# main.pyの修正
main.pyに下記を追記する。
```main.py
@app.get("/test")
def read_root():
    return {"Hello": "test"}

```

ブラウザでhttp://localhost:8000/test
を開く。
Hello testが表示される。
![スクリーンショット 2024-01-29 155014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1319419/f5925385-85f1-e76c-aa44-41166530b422.png)



# docker containerの終了＆削除
下記コマンドを実行する。
```
docker stop fastapi-tutorial
docker rm fastapi-tutorial
```

# 参考
- https://fastapi.tiangolo.com/ja/deployment/docker/
添付されたファイルを使って公開リンクを作成するフロー


# はじめに

以下を考慮していないので、実際に使うには注意が必要です。

+ 既に公開リンクが作成されていたら、再作成しないようにする
+ 複数のファイルがあった時の対応

今回は商品の表示URL欄に結果を更新します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/ce7310c1-4178-c2f4-4b5b-8da10c018a3d.png)


### 全体

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/36eae37d-f181-96be-f473-32b49f7c7dee.png)

### 変数

|変数名 |種類  |用途|
|:-----------|:----------------------|:--------------|
|recordId|テキスト|商品のIdを格納|
|ContentDistributionId|作成したContentDistributionのIdを格納|
|Product2|レコード(商品)|商品を更新するためのレコード変数|

### getProduct2

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/f2611ac6-e5f4-5ef2-d55b-bc017ae1f9e8.png)

### getContentDocumentLink

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/61a8582c-ff06-295d-e152-2a732fbc0a57.png)


### getContentDocument

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/f7a86f3d-4db4-6a16-b618-4dcbc1e4cb9c.png)

### getContentVersion 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/fc936d19-7db0-8fe6-6317-0e23c92031d5.png)


### CreateContentDistribution

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/6284e247-8200-e82d-4469-dd17592dea8a.png)


### getContentDistribution

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/41c72830-fa01-90a3-1d52-6119c68f4f2a.png)


### assignProduct2

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/07ae563d-69a5-7b54-e4a7-377bb005526a.png)


### updateProduct2

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/068ea156-1810-ee5e-5b6b-abd7baaed784.png)


# ContentDistributionを調べてみます。


ContentDocumentIdはフローで設定していないけど、自動で値がセットされています。ContentVersionIdから参照されているのかもしれないです。

このフローでContentDistributionを作ってもこの部分にはセットされません。
しかし、この機能で公開リンクを作ると、次に開いてもちゃんとURLは存在します。

DistributionPublicUrlの項目が表示されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/57bb29f4-de5f-add6-5f15-610b19520b0e.png)
【API】結局APIって何ですか？

# はじめに
<!-- 発端や概要を記載 -->
こんにちは、エンジニア2年目の嶋田です。
まずは、この記事を開いていただきありがとうございます！
先日APIという目に見えないつながりに苦戦しました…
そこで備忘録としてまとめることにしました。
初学者の方や未経験のエンジニアの方にもわかりやすく、役に立つ内容を目指します！

# 目次
- [APIとは何か](#APIとは何か)
- [Web APIとは何か](#WebAPIとは何か)
- [APIとWeb APIの違い](#APIとWebAPIの違い)
- [エンドポイントって何？](#エンドポイントって何？)
- [HTTPメソッドの基本](#HTTPメソッドの基本)
- [最後に](#最後に)

## APIとは何か
![API](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524119/b193456f-127d-5f69-4381-14fbab6c005f.png)

「API」とは、「Application Programming Interface」の頭文字を取ったものです。
この英語のフレーズを訳すと「アプリケーション・プログラミング・インターフェース」となりますが、よりシンプルに言うならば、「アプリケーションをプログラミングするための接点」という意味合いになります。

インターフェースとは、コンピュータ用語において、「何か」と「何か」を繋ぐ役割を持つものを指します。たとえば、USBは「パソコン」と「周辺機器」を繋ぐものであり、これも一種のインターフェースです。

このことから、APIは「アプリケーション、ソフトウェア」と「プログラム」を繋ぐ役割を持つものと考えることができます。具体的には、異なるソフトウェアやサービスが互いに通信するための橋渡し役として機能します。

例えば、レストランや美容室の店舗のウェブサイトにGoogle マップの地図が埋め込まれていることが多くありませんか？
あれが！まさに！**APIのおかげ**で実現しています！
このように、APIは私たちが日常的に利用するさまざまなサービスの背後で重要な役割を果たしています。

Google Maps APIの使用方法が気になった方はこちらの記事を参考にしてみてください！

https://qiita.com/Haruka-Ogawa/items/997401a2edcd20e61037


## WebAPIとは何か
APIの一種として、「Web API」についても触れておきたいと思います。
APIについて調べていると、REST APIやSOAPのようにさまざまな名前が挙がってきませんか？
私自身、調べていて混乱した理由の一つでした…

そこで、まず押さえておくといいなと感じたものが「**WebAPI**」です。

「Web API」って聞くと少し難しそうですが、実は私たちの身の回りに溢れています。
簡単に言えば、Web APIはインターネット上で動くAPIのことです。
これにより、ウェブサイトやアプリが他のサービスとデータをやり取りできるんです！
例えば、あなたがFacebookやTwitterでログインする機能、これもWeb APIのおかげで実現しています。
また、ウェブサイトに表示される天気予報や、ニュースの最新情報も同じくWeb APIを利用しています！

まとめると
Web APIは、インターネット上で提供されるAPIのことで、HTTPプロトコルを使用してサービスやアプリケーション間で情報を交換します。具体的には、ウェブサービスやアプリが他のサービスの機能やデータを利用するために使用される技術です。

## APIとWeb APIの違い
APIとWeb APIの大きな違いは、利用される場所です。通常のAPIはソフトウェアやシステムの内部で使われ、異なる部分同士をつなぐ役割を持っています。一方、Web APIはインターネットを介して外部のサービスと連携するために使われます。つまり、Web APIはもっと広い世界(よりオープンでアクセスしやすい性質)で活躍していて、異なるプログラムやアプリケーションがインターネットを通じて情報を交換する際に使用されています。

## エンドポイントって何？
APIの作成方法や概念について調べていると「エンドポイント」とたくさん出てきませんか？
エンドポイントは、簡単に言うとWeb APIの「住所」みたいなものです。特定のURLにアクセスすることで、特定の情報やサービスを取得できるようになっています。例えば、`https://api.weather.com/current` というURLは、天気予報APIのエンドポイントで、ここにアクセスすると現在の天気情報を取得できます。このURLにリクエストを送ることで、APIは必要なデータを返してくれるということです！

## HTTPメソッドの基本
Web APIとの通信には、「HTTPメソッド」と呼ばれる操作が使われます。これはWebサーバーに何をして欲しいかを伝える方法です。基本的なHTTPメソッドには以下があります。

- **GET**: データの取得に使われます。例: `GET /api/items` はアイテムのリストを取得します。
- **POST**: 新しいデータを作成するのに使われます。例: `POST /api/items` は新しいアイテムを作成します。一般的には「PUT」が更新に使われることが多いです。PATCHは部分的な更新に特化しています。
- **PATCH**: 既存のデータを更新するのに使われます。例: `PATCH /api/items/1` はIDが1のアイテムを更新します。
- **DELETE**: データを削除するのに使われます。例: `DELETE /api/items/1` はIDが1のアイテムを削除します。

# 最後に
私自身まだまだ勉強中なので、何か問題がありましたら教えてください！
この記事が皆さんの知識の一部となり、APIに対する理解を深める手助けになれば幸いです。
読んでいただき、ありがとうございました！
Electron でWindowsへのコード署名を気軽にCI/CDで行うことはもはや無理っぽい

コードサイン用のキーを更新したら、謎のUSBで送られてきたので、ちょっと嫌な予感がして調べたら、 **EVだけでなくOVもHSM(hardware storage module)以外は2023年6月以降非対応になりました** とのこと。[Electron Forge/Builder でUSBトークンを使用したコード署名](https://qiita.com/komde/items/c9749296802cedf4c015)をローカルで行う必要があります。ちーん、、、

https://www.electronforge.io/guides/code-signing/code-signing-windows

## （2024−08−04追記） CloudHSMを使用するとどれぐらい大変なのか？

[How to Integrate a GitHub Actions CI/CD Pipeline with CodeSigning?](https://www.encryptionconsulting.com/how-to-integrate-a-github-actions-ci-cd-pipeline-with-codesigning/) に詳細に説明がありました。ザクッと山場は

- HSM対応の証明書の取得(GrobalSignあたりはオプションがあるようです)
- 専用クラスタの作成
- Github Action で独自ランナーを指定

という感じになるかとは思うのですが、専用のランナーを用意するということはその環境のメンテナンスも必要になるということで、CI/CDのメリットを半分以上削いでしまう気もします、、。ということで、自分のところでは心を無にしてローカルビルドすることにしました。
【2024年1月】Google の生成AI関連のキーワードまとめ

# 【2024年1月】Google の生成AI関連のキーワードまとめ

Google はもともと ML や AI 分野に力を入れていた印象ですが、2023年以降はそれが加速し、いろんなサービスや機能がリリースされました。
遅ればせながらこのあたりをキャッチアップしようとしていますが、その第一歩として生成AIの文脈でよく聞くキーワードについて調べました。

## サービス
### Bard
Google が開発した対話型AIサービスで、生成AI の火付け役となった ChatGPT と同等の位置づけです。
使っているモデルは PaLM2 と Gemini です。
テキストや画像を使った質問への回答はもちろん、Google マップや Google フライトなどの各機能を使った回答を返すこともできます。

https://japan.googleblog.com/2023/05/bard.html

https://japan.googleblog.com/2023/09/bard.html

### Vertex AI
Google Cloud の機械学習プラットフォームです。
Bard が一般ユーザー向けサービスだったのに対し、Vertex AI は開発者向けサービスです。
機械学習のワークフロー（データの準備→モデルのトレーニング→モデルの評価と反復→モデルのサービング→モデルのモニタリング）をすべて Vertex AI 上で行うことができます。
Google やサードパーティが提供するモデルを使うこともできますし、自分でモデルをトレーニング・デプロイすることもできます。

https://cloud.google.com/vertex-ai/docs/start/introduction-unified-platform?hl=ja

#### Model Garden
Google や オープンソース、サードパーティが提供するモデルを集めたプラットフォームです。モデル用のマーケットプレイスのようなものです。
2024年1月時点で130以上のモデルが提供され、Model Garden で提供されているモデルは Vertex AI でデプロイ可能です。

https://cloud.google.com/model-garden?hl=ja

### Duet AI
Google の各種サービス上で使える AI 機能が Duet AI です。

#### Duet AI for Google Workspace
Google Workspace のサービスの中で AI の支援を受けることができます。
例えば、

 - GMail で、概要を提示すると本文の下書きを提供する
 - Google ドキュメントで、別のドキュメントを活用して新たな文章を作成する
 - Google Meet で、リアルタイムで翻訳しその内容を字幕で提供する

使用しているモデルは PaLM2 です。

https://workspace.google.com/solutions/ai/

#### Duet AI for Google Cloud/developers
2023年の Google Cloud Next Tokyo では「Duet AI for Google Cloud」という名称で発表されていたと記憶していますが、執筆時点では「Duet AI for developers」という名称が公式ドキュメントで使用されています。
Duet AI for Google Workspace と同じく、Google Cloud のサービスの中で AI 支援を受けることができます。

 - コードエディタ上でコードアシスタンスを行う
 - コンソール画面で、自然言語のチャットを開き Google Cloud に関する質問に回答する
 - Cloud Logging でログの要約やトラブルシューティングを行う

https://cloud.google.com/duet-ai?hl=ja

## モデル
### PaLM・PaLM2
Google が開発する大規模言語モデルです。
2022年5月に PaLM が、2023年5月に PaLM2 が発表されました。
前述した様々なAIサービスのモデルとして使われている他、セキュリティ特化したモデル Sec-PaLM2, 医療機関向けに特化した Med-PaLM 2 のベースになっています。

https://www.infoq.com/jp/news/2022/05/google-palm-ai/

https://ai.google/discover/palm2/

https://cloud.google.com/security/ai?hl=ja

https://cloud.google.com/blog/ja/topics/next-tokyo/chugai-introduces-use-of-generated-ai

### Gemini

Gemini はマルチモーダルモデル（画像、動画、テキストなどの複数のモダリティから情報を処理できるモデル）で、Bard や Vertex AI で試すことができます。
PaLM2 はテキストデータのみをインプットにできたのに対し、Gemini は画像などもインプットにすることができる、という認識です。
Gemini のリリース時高いパフォーマンスが話題になりましたが、Gemini の公式ドキュメントには GPT-4V との性能比較表が掲載されています。

https://deepmind.google/technologies/gemini/

https://cloud.google.com/vertex-ai/docs/generative-ai/multimodal/overview?hl=ja

### Codey
前述の PaLM 2 がベースとなっている、ソースコード特化のモデルです。
自然言語からソースコードを生成する機能やチャット上でソースコード関連の質問に回答する機能、ソースコード記述時にオートコンプリート候補を提示する機能があります。

https://cloud.google.com/vertex-ai/docs/generative-ai/code/code-models-overview?hl=ja

### Imagen
画像に特化したモデルです。
テキストから画像の生成・編集をする機能や画像より説明テキストや質問回答を得る機能などがあります。

https://cloud.google.com/vertex-ai/docs/generative-ai/image/overview?hl=ja


以上です。
生成AI 関連のアップデートはとても速いので、これが概要をつかむための参考になれば幸いです。
Node.jsからCloudflare R2に動画ファイルをアップロードしてみるメモ


R2に動画ファイルをアップロードしてみます。

## 通常はCloudflare Workers上からアップロードするのが良い

ただ重たい処理などがあるとCloudflare workers上だと処理がキャンセルされてしまうことがあります。

- 重たいファイルを扱う場合
- その他単純にR2を外部から使いたい

などの時はNode.jsからアップロードするという選択肢も持っておくと良さそうでした。

## node-cloudflare-r2

パッと調べて出てきたこのライブラリが手軽でありがたかったです。

https://www.npmjs.com/package/node-cloudflare-r2 

```js
$ npm i node-cloudflare-r2
```

`accountId`、`accessKeyId`、`secretAccessKey`の3つのキーはCloudflare R2のページから取得できます。
`https://xxxxxxxxxxxxxxxxxxxxxx.r2.dev`といった形のPublic URLも必要ですが、同じくページから確認できます。

```js
const {R2} = require('node-cloudflare-r2');

const r2 = new R2({
    accountId: '<AccountId>',
    accessKeyId: '<AccessKeyId>',
    secretAccessKey: '<SecretAccessKey>',
});

const bucket = r2.bucket('testbucket');

const main  = async () => {
    // Set your bucket's public URL
    bucket.provideBucketPublicUrl('https://xxxxxxxxxxxxxxxxxxxxxx.r2.dev');

    console.log(await bucket.exists());
    // true

    //第1引数: ローカルファイル名
    //第2引数: バケット上で保存する名前
    //第3引数: customMetaData
    //第4引数: ファイルのMIMEタイプ
    const upload = await bucket.uploadFile('./test.mp4', 'test.mp4', '', 'video/mp4');
    console.log(upload);
    /*
    {
        objectKey: 'destination_file_name.ext',
        uri: 'destination_file_name.ext',
        publicUrl: 'https://pub-xxxxxxxxxxxxxxxxxxxxxxxxx.r2.dev/destination_file_name.ext',
        etag: '',
        versionId: '',
        }
    */

}

main();
```

## MIMEタイプ指定が独特

現状のバージョン(`"node-cloudflare-r2": "^0.1.5"`)だとそのまま送ると`application/octet-stream`というMIMEタイプになります。

> R2の管理画面上
> ![スクリーンショット 2024-01-26 0.17.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/c94bc313-8ee8-8695-301f-bb46c14005d9.png "スクリーンショット 2024-01-26 0.17.51.png")

そこでMIMEタイプを指定したいのですが、何故かKey-Valueではなく配列で送る感じになっていました。(中までは見てない...)

```js
    //第1引数: ローカルファイル名
    //第2引数: バケット上で保存する名前
    //第3引数: customMetaData
    //第4引数: ファイルのMIMEタイプ
    const upload = await bucket.uploadFile('./test.mp4', 'test.mp4', '', 'video/mp4');
```

こんな感じで第四引数がMIMEタイプです。今回動画をアップロードしたかったのでここにvideo/mp4を指定します。

こんな形でアップロードするとちゃんとMIMEタイプがvideo/mp4になりました。

> ![スクリーンショット 2024-01-29 14.42.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/ffdaf50c-fe85-20a9-e014-b4f0ac5fcaac.png "スクリーンショット 2024-01-29 14.42.48.png")


参考: [application/octet-stream【MIMEタイプ】](https://wa3.i-3-i.info/word15821.html)
Laravel ExcelのCSVインポートで、日本語のカラム名を取得できない問題。

# ヘッダーのカラム名を取得

エンコーディングの問題以前に、そもそもヘッダーの行を正常に取得できていなかった。
以下設定でformatterをnoneにすれば解決する。

```config/excel.php
'imports' => [
    'heading_row' => [
        'formatter' => 'none',
    ],
],
```

クラス毎に設定する場合は以下。
```Imports/TestImport.php
use Maatwebsite\Excel\Imports\HeadingRowFormatter;

HeadingRowFormatter::default('none');

class TestImport implements ToModel
{
}
```

# シフトJISの文字化け

先程のconfig/excel.phpでも設定できるが、
クラスに設定する場合は、getCsvSettings()を追記する。
WithCustomeCsvSettingsをimplementsすることも忘れずに。

```Imports/TestImport.php
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithCustomCsvSettings;

class TestImport implements ToModel, WithHeadingRow, WithCustomCsvSettings
{
    public function model(array $row)
    {
        return new User([
            'name' => $row['名前'],
            'email' => $row['メールアドレス'],
        ]);
    }

    public function getCsvSettings(): array
    {
        return [
            'input_encoding' => 'SHIFT-JIS'
        ];
    }
}
```
WSLにrcloneをインストールgitリポに保存するほどじゃないファイルを管理する方法

# WSLにrcloneをインストールして、gitリポに保存するほどじゃないファイルたちを管理する方法

WSL（Windows Subsystem for Linux）を使ってLinuxの環境をWindowsで楽しんでいます。WSLはWindowsとLinuxの両方の機能にアクセスできるので、開発者にとってとても便利です。家と職場の両方から参照したいけど、gitリポに保存するほどじゃないファイルたちです。gitリポに保存すると、履歴が膨大になったり、プライベートな情報が漏れたりする可能性があります。WSLにrcloneというツールをインストールして、クラウドストレージにファイルを同期する方法を紹介したいと思います。

## rcloneとは？

rcloneとは、コマンドラインから様々なクラウドストレージにアクセスできるツールです。Google DriveやAmazon S3などの有名なサービスはもちろん、FTPやSFTPなどのプロトコルにも対応しています。rcloneを使えば、ローカルのファイルとクラウドのファイルをコピーしたり、同期したり、移動したり、削除したりできます。また、マウント機能を使えば、クラウドのファイルをローカルのドライブとして扱うこともできます。

## WSLにrcloneをインストールする方法

WSLにrcloneをインストールするには、以下の手順を実行します。

1. rcloneの公式サイトから、環境に合ったインストーラをダウンロードします。
1. 今回は、Ubuntu 20.04を使っているので、Linux用のインストーラを選びました。
2. ダウンロードしたファイルを任意のフォルダに解凍します。
2. ここでは、`~/rclone`というフォルダに解凍しました。
3. 解凍したフォルダに移動して、`rclone`という実行可能ファイルを`/usr/bin`にコピーします。
 
 
これで、どこからでもrcloneコマンドを使えるようになります。

```bash
cd ~/rclone
sudo cp rclone /usr/bin
```

### rcloneの設定ファイルを作成します。

`rclone config`というコマンドを実行すると、対話式のメニューが表示されます。ここでは、Google Driveにアクセスするための設定を行いました。詳細な設定方法は、rcloneのドキュメントを参照してください。

```bash
rclone config
```

設定が完了したら、`rclone listremotes`というコマンドで、作成したリモートの一覧を確認できます。ここでは、`gdrive:`という名前でGoogle Driveのリモートを作りました。

```bash
rclone listremotes
gdrive:
```

## gitリポに保存するほどじゃないファイルたちをクラウドに同期する方法

WSLにrcloneをインストールして、クラウドのリモートを作成したら、あとは簡単です。`rclone sync`というコマンドで、ローカルのファイルとクラウドのファイルを同期できます。例えば、`~/Documents`というフォルダをGoogle Driveの`Documents`というフォルダに同期するには、以下のようにします。

```bash
rclone sync ~/Documents gdrive:Documents
```

これで、`~/Documents`にあるファイルがGoogle Driveの`Documents`にも反映されます。逆に、Google Driveの`Documents`にあるファイルが`~/Documents`にも反映されます。同期するときに、削除や上書きが発生する場合は、確認メッセージが表示されます。`-P`オプションを付けると、同期の進捗状況が表示されます。

```bash
rclone sync -P ~/Documents gdrive:Documents
```

同期するファイルやフォルダを絞りたい場合は、`--include`や`--exclude`というオプションを使って、パターンを指定できます⁷。例えば、`*.txt`という拡張子のファイルだけを同期するには、以下のようにします。

```bash
rclone sync --include "*.txt" ~/Documents gdrive:Documents
```

同期するのではなく、コピーしたい場合は、`rclone copy`というコマンドを使います⁸。これは、ローカルのファイルをクラウドにコピーするだけで、クラウドのファイルをローカルにコピーしないという違いがあります。また、削除や上書きは発生しません。例えば、`~/Pictures`というフォルダをGoogle Driveの`Pictures`というフォルダにコピーするには、以下のようにします。

```bash
rclone copy ~/Pictures gdrive:Pictures
```

## まとめ

今回は、WSLにrcloneをインストールして、gitリポに保存するほどじゃないファイルたちをクラウドに同期する方法を紹介しました。rcloneを使えば、コマンドラインから簡単にクラウドストレージにアクセスできるので、WSLで作成したファイルの管理に便利です。もちろん、WSL以外の環境でも使えますし、クラウドストレージの種類も自由に選べます。ぜひ、rcloneを試してみてください。
Salesforce ファイルのパブリック URL の生成

+ [Generating Public URL for Salesforce Files](https://forcepanda.wordpress.com/2021/05/04/generating-public-url-for-salesforce-files/)

Salesforce では、Content Delivery オブジェクトを使用してこれを非常に効果的に処理できます。API 名: [ContentDistribution](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_contentdistribution.htm)


ファイルを公開するには、それぞれの ContentVersion ID へのリンクを含む ContentDistribution オブジェクトにレコードを作成するだけです。

ContentDistribution タイプのレコードを作成すると、自動的に入力されるフィールドが 2 つあります。DistributionPublicUrl と ContentDownloadUrl。

これらのフィールドには両方とも、ファイルをパブリック リソースとして公開するための URL が含まれています。何が違うのかと思ったら…

DistributionPublicUrl には、コンテナ内でプレビューできる共有ファイルの URL が含まれています。そしてそれは次のようになります:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/44207602-74b7-4ac1-5050-a1a17b6765c5.png)


この URL を使用すると、ファイルをプレビューしてダウンロードできます。ただし、これを img タグで使用してイメージ タイプのファイルをプレビューする場合は機能しません。

では、どうやってそれを機能させるのでしょうか?
ContentDownloadUrl フィールドに対応します。

ContentDownloadUrl には、ファイルを直接ダウンロードできる共有ファイルの URL が含まれています。そして、この URL を img タグ内でソース (src) として使用して、ファイルを表示することができます。

さらにすごいのは、ContentDistribution オブジェクトが、ViewCount、FirstViewDate、LastViewDate など、他の便利なものも追跡していることです。共有ファイルをパスワードで保護することもできます。

また、ファイルが公開されているさまざまな場所に基づいて統計を追跡したい場合は、同じファイルに対して複数の ContentDistribution レコードを作成します。

このオブジェクトを使って実行できることは他にもたくさんあります。ここを確認してください。

# ContentDistribution オブジェクト レコードを作成するにはどうすればよいですか?


これを行うには、ファイルページ、Apex、またはフローの「パブリックリンク」クイックアクションを使用できます。

パブリック リンクの使用 クイック アクション:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/3ef9c6ef-a369-f865-0254-4e7f0f5d0e3b.png)


リンクが生成されると、バックグラウンドで ContentDistribution オブジェクト レコードが作成されます。

注: 生成されるリンクは DistributionPublicUrl です 。したがって、「ソース」URL として使用したい場合は、ContentDownloadUrl を個別にクエリする必要があります。

**Apex の使用:**

```Java
/* Getting ContentVersion file using ContentDocument Id */
ContentVersion file = [SELECT Id, Title FROM ContentVersion WHERE ContentDocumentId = '<Content Document ID>'].Id;

/* Creating ContentDistribution record */
insert new ContentDistribution(
   Name = file.Title,
   ContentVersionId = file.Id,
   PreferencesAllowViewInBrowser= true

);
```

**フローの使用:**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/f616f632-b152-6cf9-944a-5598fca66336.png)



補足: ContentAsset(Asset files) を使用してファイルをパブリック リソースとして公開することもできますが、これはこのアプローチよりも少し複雑です。
環境変数PIPENV_VERSIONを使ってはいけないらしい

CIでpipenvを使おうとするとハマったのでメモ
日本語の文献が全然出てこないので書き残しておきます

`pipenv<=2023.11.17` で再現する模様

# 発生していること
pipenvコマンドを実行するときに、環境変数 `PIPENV_VERSION` を設定しているとエラーが発生する


```
❯ pipenv run echo hello
Loading .env environment variables...
hello
```

```
❯ PIPENV_VERSION="2023.11.17" pipenv run echo hello
Usage: pipenv [OPTIONS] COMMAND [ARGS]...
Try 'pipenv -h' for help.

Error: Invalid value for '--version': '2023.11.17' is not a valid boolean.
```


通常利用だと `pip install pipenv=2023.11.17` のようにコマンド上で直接指定することがほとんどだと思うが、CI上だと環境変数を利用することが大半のはず

これはgithub actionsでの例
```github-actions.yml
env:
  PYTHON_VERSION: "v3.11.1"
  PIPENV_VERSION: "2023.11.15"

jobs:
  setup:
    steps:
    - name: install python
      uses: actions/setup-python@v5
      with:
        python-version: ${{ env.PYTHON_VERSION }}

    - name: install pipenv
      run: |
        python -m pip install --upgrade pip
        python -m pip install pipenv=="${{ env.PIPENV_VERSION }}"

    - name: install python dependencies by pipenv
      run: |
        pipenv sync  # このコマンドを実行しようとすると Invalid value が発生する
```

# 原因
`PIPENV_VERSION` はpipenvが依存しているパッケージ[click](https://pypi.org/project/click/)によって予約されている環境変数なので触れてはいけない…というのが答えらしい

https://github.com/pypa/pipenv/issues/3633#issuecomment-478250721


# 対処方法
`PIPENV_VERSION` を `PIPENV__VERSION` に書き換えるなど、1文字でも変更してしまえばOK


# 関連リンク

- https://github.com/pypa/pipenv/issues/3633
- https://github.com/pypa/pipenv/issues/5627
メッセージボックス

```
using System;
using System.Windows.Forms;

class Program
{
    static void Main()
    {
        ShowMessageBox("Hello, World!");
    }

    static void ShowMessageBox(string message)
    {
        // 既に同じメッセージが表示されていないか確認
        if (!IsMessageBoxShowing(message))
        {
            MessageBox.Show(message);
        }
    }

    static bool IsMessageBoxShowing(string message)
    {
        // メッセージボックスが表示されているかどうかを確認するロジックを実装
        foreach (Form form in Application.OpenForms)
        {
            if (form is MessageBox && ((MessageBox)form).Text == message)
            {
                return true;
            }
        }
        return false;
    }
}
```
```
using System;
using System.Linq;
using System.Windows;

namespace WpfMessageBoxExample
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void ShowUniqueMessageBox(string message)
        {
            // 既に同じメッセージが表示されていないか確認
            if (!IsMessageBoxShowing(message))
            {
                MessageBox.Show(message);
            }
        }

        private bool IsMessageBoxShowing(string message)
        {
            // 開いているすべてのウィンドウを取得し、同じメッセージを持つウィンドウが存在するか確認
            return Application.Current.Windows.OfType<Window>()
                .Any(window => window is MessageBox && ((MessageBox)window).Title == message);
        }

        private void ShowMessageBoxButton_Click(object sender, RoutedEventArgs e)
        {
            ShowUniqueMessageBox("Hello, World!");
        }
    }
}
```
Python3 エンジニア認定基礎試験 合格してみた

# Python3 エンジニア認定基礎試験 合格しました。
試験日：2024年1月27日
スコア：800/1000点
合否：合格

## 使用教材
【書籍】
・Pythonチュートリアル第4版
・Python 3 エンジニア認定[基礎試験]問題集

【Webサイト】
・ExamApp：模擬試験アプリ
・diver - DIVE INTO CODE Python3エンジニア認定基礎模擬試験
・prime-strategy Python3エンジニア認定基礎模擬試験


## スケジュール
勉強期間は、2023年12月12日 ~　2024年1月26日 
1日の勉強時間は平均1時間~3時間程度でした。

１．（2023.12.12 ~ 2023.12.22）
最初の1週間は、Pythonチュートリアル第4版を読みました。


２．（2023.12.23 ~ 2024.1.10)
Python 3 エンジニア認定[基礎試験]問題集を解きました。


３．（2024.1.11 ~ 2024.1.23)
Webサイトの模擬問題を解きました。
・ExamApp：模擬試験アプリ
・diver - DIVE INTO CODE Python3エンジニア認定基礎模擬試験
・prime-strategy Python3エンジニア認定基礎模擬試験

４．(2024.1.24 ~ 2024.1.26)
最後に、模擬を一通り解いたり、問題集を一通り解いたり、不正解の箇所を学びなおし、試験に備えました。

５．(2024.1.27)
試験本番

## 感想
Pythonを未経験から勉強して、無事合格することができました。
Pythonの基礎的なことがわかりましたが、次は**Python3エンジニア認定データ分析試験**を目指して勉強を続けようと思います。

## 次の目標
**Python3エンジニア認定データ分析試験**
【JSTQB ALTM】シラバスまとめ（第6章）

<iframe src="https://www.slideshare.net/slideshow/embed_code/key/Hm5jmKCoQ1Akjt?hostedIn=slideshare&page=upload" width="476" height="400" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>

:::note warn
筆者（私）独自の解釈・理解をまとめた資料のため、誤りがある可能性があることにご留意ください
:::
XcodeにStripeのフレームワークを入れる

　File -> Add Add Packages depe...を開いてhttps://github.com/stripe/stripe-ios-spmで検索してインポート

 TARGET -> Build Phases -> Link Binary With...にStripePaymentSheetを追加
 アイコンに注意![スクリーンショット 2024-01-29 12.54.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117011/b158d7cc-f652-4991-7b5a-b9e32544df2f.png)
【ChatGPT有＋DALL-E3】描画の指示をしていないのに、しちゃうって……


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

　今回は、描画の指示をしていないのに、描画してしまうのを、なんとかしましょう。

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

　先日、
　　OpenAIが
　　　恋人GPTsを削除しました。

　そして、またです。

　今度は、
　　大統領候補者なりすましAIの
　　　開発者のアカウントを凍結。
[OpenAI、大統領候補者なりすましAI「Dean.Bot」開発者のアカウント凍結](https://ledge.ai/articles/openai_suspends_developer_behind_dean-phillips-bot)

　以前に、
　　OpenAIは、
　　　選挙などに加担しない、と
　　　　表明していました。
　　　　　言い方は違いますけどねw
***
　さて、
　　本題です。

　描画の指示を
　　していないのに
　　　描画してくれるのは
　　　　ありがたいのですが、
　　　　　ときにはテキストの方を
　　　　　　優先してもらいたい、
　　　　　　　ですよねw

　こういうときは、
　　プロンプトの最初に
　　　“描画なし。”と
　　　　書き込んでおけば
　　　　　わかってもらえます。
2024/01/29 14:21
ごめんなさい、
　嘘を書きました。

正しくは、
　プロンプトの最後です。

申し訳ありませんでした。
2024/01/29 14:21

　最初から
　　書き込まねば
　　　ならないのは
　　　　面倒ですが、
　　　　　パソコンやスマホの
　　　　　　文字入力機能に
　　　　　　　単語登録しておけば
　　　　　　　　すぐに入力できます。

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

　今回は、ここまで。
ubuntu install docker

```
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

sudo chmod 666 /var/run/docker.sock
```
laravel 結局カスケードを使った削除とEloquentモデル間リレーションを使った削除ってどう違うのさ

## 概要

自分の中でカスケードを使った関連テーブル削除とEloquentモデル間リレーションを使った削除の違いがあやふやだったので簡単にまとめてみる。

## 結論

やってることはどちらも「メインテーブルのレコード削除時に関連テーブルのレコードも削除する」ことなので一緒
ただし方法が異なる。
メリット・デメリットがあるのでそれぞれ要件に合った方法で行おう

## カスケードを使った削除

| 項目 | 内容 | 備考 |
| --- | --- | --- |
| レイヤー | データベース |  |
| 設定場所 | マイグレーションファイル | 外部キー制約と一緒に定義する |
| メリット | パフォーマンスが高い:<br>DBだけで完結するので関連するデータが膨大な場合に向いている<br>アプリ側でのトランザクション不要:<br>DBが勝手に整合性の担保をしてくれる<br>トランザクションを設定するコストやそもそもアプリケーション側でトランザクション処理が発生しない |  |
| デメリット | わかりにくい:<br>定義場所がマイグレーションファイルになるためコードから読み取りにくい<br>意図しない削除が発生しかねない:<br>周知されていないと一見問題なさそうなコードでもデータ大量削除という事故が起こりかねない | |

## Eloquentモデル間リレーション

| 項目 | 内容 | 備考 |
| --- | --- | --- |
| レイヤー | アプリケーション |  |
| 設定場所 | （モデルクラス） | 明示的に削除のみの設定をすることはない |
| メリット | わかりやすい:<br>どのテーブルとどのテーブルが関連しているかがわかりやすい<br>コード上だけで追うことができる<br>柔軟性:<br>ビジネスロジックに応じて削除範囲を変えたい場合などに便利 |  |
| デメリット | トランザクションは自分で設定:<br>勝手に整合性管理してくれないのでトランザクションを自分たちで実装する必要がある<br>処理コスト増:<br>関連するレコードを削除する際、関連テーブル削除クエリをフレームワーク側が発行して実行する。<br>「クエリを考えてクエリを実行」する時間があるのでコストがかかる|  |

## まとめ

| 項目 | カスケード削除 | モデル間リレーション削除 |
| --- | --- | --- |
| 大量のデータ削除 | ◎ | △ |
| 厳格なデータ整合性（退会ユーザーの削除時など） | ◎ | ○（トランザクション実装時） |
| 削除時にビジネスロジックを付与| ✕ | ○ |
| わかりやすさ | △ | ◎ |
MacのターミナルからOSアップデート

## やりたいこと
- MacのターミナルからOSをアップデートする

## 手順
1. アップデートがあるか確認
`softwareupdate --list`
1. 1でmacOSが表示されたら、`softwareupdate -i --os-only`
（ダウンロード後に再起動させる場合）`softwareupdate -iR --os-only`
[RubyMine]消せないTypeScriptの警告の消し方

RubyMineユーザーなら誰しもが見たことがあるであろう、警告を表す赤い波線。
これを放置しておくと大抵プログラマにとって嬉しくないことが起きるので、なるべく早い段階で消しておきたいですよね。
今回は「問題のないコードなのに出る。しかも消しづらい。」という厄介な警告に悩まされたので、その対策をまとめておきます。

茶番が多いので解決方法だけ知りたいかたは[まとめ](#まとめ)へGo！

## TypeScriptのany型に関する警告が消えない
以下の画像は今回遭遇した問題の警告の一例です。

TypeScriptの関数呼び出しのコードに[no-unsafe-call](https://typescript-eslint.io/rules/no-unsafe-call/)の警告が出ていますね。
「ちゃんとお型づけしなさいよ・・・」と思うかもしれませんが、**createCheckinの型はきちんと別ファイルに定義されています。**
その証拠に、ターミナル上でESLintを走らせても問題なくパスします。

つまり、RubyMineが問題のないコードに対して警告を表示してしまっているという状態になっています。

![スクリーンショット 2024-01-22 17.07.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567079/5fe48a15-00f8-8c6b-cfa0-0b567d165a79.png)

上で述べたように、この警告が出ていると良くない事が起きる前兆なのでどうやったって気になります。無視できません。
それなのに、実際には問題のないコードなので、警告の内容に対応して消すこともできません。
この言わば「詐欺警告」は生産性をゴリゴリ下げてくるので、対策が必要でした。

## なぜ詐欺警告が表示されてしまうのか
上で述べた警告が出現する状況は以下のようなケースが多かったように感じます。

- 型を別ファイルに定義している
- ブランチを切り替えた直後
- ブランチを切り替える前と後で型を定義しているファイルに差分がある

どうやらESLintには結果をキャッシュするような機能があるらしく、これらのことから、**<INS>ブランチを切り替えた際にRubyMine側のESLintが最新の型情報を取得できていないことが原因なのではないか？</INS>** と睨みました。

## 詐欺警告を消すたった一つの方法...？
となれば、ESLintに最新の型情報を読み込んでもらう方法を見つけられれば、にっくき詐欺警告ともおさらばできます。
ただ、RubyMine側のESLintの問題なので、ファイルを開き直そうがRubyMineのTypeScriptを再起動しようがヤツらはのさばってきます。

そんなしつこいヤツらを撃退するたった一つの方法。

それは

**「プロジェクトを開き直す」**

です。

左上の❌ボタンもしくは「Close Project」でプロジェクトを閉じて、もう一度開き直します。
するとあら不思議、ヤツらは跡形もなく消え去っています。
これはプロジェクトを開き直した際にESLintが再起動され、最新の型情報を取得するからだと思われます。

☺️　< 「これにて一件落着！！！」

とはなりませんよね。
プロジェクトを開き直すとか面倒臭すぎてあり得ないです。

## 解決策：ESLintを再起動するプラグインを使う
どうやらVSCodeには`TypeScript: Restart TS server`という便利なコマンドがあるらしく、VSCodeへの乗り換えを考えていた時期が自分にもありました。
ただ長年連れ添ったRubyMineに簡単に別れを告げられるほど薄情な人間ではなかった自分は解決方法を探しました。

そこで見つけたのが以下のissueでした。

https://youtrack.jetbrains.com/issue/WEB-38066/Add-ability-to-restart-eslint-service

そこには自分と同じように詐欺警告にいきりたっている同志達がいました。
そのうちの一人の投稿に救われました。

![スクリーンショット 2024-01-27 16.26.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567079/32678138-6964-b0f3-3695-67ef3a1a411b.png)

神はここにいた・・・！:pray:
怒りを力に変えてESLintを再起動させる以下のプラグインを作成してくれた御方がいらっしゃいました。
レビュー評価が4.9なのにも頷けます。

https://plugins.jetbrains.com/plugin/14119-eslint-restart-service-action

上記のプラグインをRubyMineにinstallして、ショートカットなどを設定してあげる（自分は⌘⌥Sに設定しています）ことで、無事、詐欺警告達との戦いに終止符を打つことができました:clap:

## まとめ
消せないTypeScriptの警告を消すには[ESLintを再起動するプラグイン](https://plugins.jetbrains.com/plugin/14119-eslint-restart-service-action)を使ってください。

同じ問題を抱えている人が多そうなのにRubyMineにESLintを再起動する機能がデフォルトで組み込まれてないことに驚きました。（自分が知らないだけで既にあるかも...？:thinking_face:）
もし、もっと簡単に解決する方法があればコメントなど頂けると喜びます。

ただ、1ヶ月前に「この機能がWebStorm（RubyMineのJS版みたいなやつ）に組み込まれていないなんて信じられるか...？」というコメントがあるので対応していないっぽい。
がんばれJetBrains！！💪

![スクリーンショット 2024-01-27 16.56.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567079/462db770-8afd-3fb7-0aff-3fce57ac0604.png)
SPSS Modelerで表を探す

RDB内に多くのテーブルがある場合、目的のテーブルを探すのは大変なことがあります。
そのヒントについてお話しします。

# 1.スキーマ名で絞り込む

「所有者」にスキーマ名をいれて「更新」をクリックすると、そのスキーマに限定して表を絞り込むことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/9140a0e9-b0bd-b783-651c-72a2615fcd4a.png)



# 2.表名で絞り込む
「名前」に表名をいれて絞り込むこともできます。DBによってはワイルドカードを使うこともできます。Db2の場合ですと「％」になります。
* 下線文字 (_) は、任意の 1 文字を表します。
* パーセント記号 (%) は、ゼロ個以上の文字のストリングを表します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/8b230790-9615-a7a3-bb7c-b23c301e81b9.png)
#### 参考　LIKE 述部
https://www.ibm.com/docs/ja/db2/11.5?topic=predicates-like-predicate

# 3.表の種類で絞り込む
テーブルであるもしくはビューであるということを知っている場合は、その種類で絞り込むこともできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/2da173bb-0174-e3a3-3f6b-b5a7f168120a.png)

# 4.条件の保存
「デフォルトとして設定」をクリックしておくと、次回開いたときにも条件が残っていますので便利です。「所有者」は記憶させておいた方が便利なことも多いかと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/4096fb0c-1656-d07b-d42b-bd380ec3ecb6.png)

# テスト環境
 
- Modeler 18.5
- Windows 11 64bit
- Db2 Warehouse on Cloud
Ruby 3.3.0 Rails 7.1.3 でYJITを有効にする

あるWebアプリケーションの Ruby on Rails のバージョンを`7.1.3`に上げました。 Ruby のバージョンを`3.3.0`に上げました。

ついでにYJITを有効にしました。
[Enable YJIT · pubannotation/pubannotation@f9284cd](https://github.com/pubannotation/pubannotation/commit/f9284cd97a57af10e05b33360c0c45634749a97e)
次のファイルを追加しました。

```ruby:config/initializers/enable_yjit.rb
if defined? RubyVM::YJIT.enable
  Rails.application.config.after_initialize do
    RubyVM::YJIT.enable
  end
end
```

運用中に何かの理由で無効にしたくなったら、コメントアウトするかファイルごと削除します。
この方法は、最新のRuby on Railsに取り込まれているそのままです。

https://github.com/rails/rails/blob/main/railties/lib/rails/generators/rails/app/templates/config/initializers/enable_yjit.rb.tt

## YJITとは

Rubyを高速に実行する機能です。Ruby 3.3 から Ruby on Rails に適用するのも実用的になったそうです。次の記事で詳しく説明されています。

[Ruby 3.3 YJITのメモリ管理とRJIT 〜すべてが新しくなった2つのJITを使いこなす | gihyo.jp](https://gihyo.jp/article/2024/01/ruby3.3-jit)

> RubyはJust-In-Time（JIT）コンパイラという機能を備えており、これを有効化すると実行時に機械語を生成して様々な最適化が行なわれ、実行が高速になります。Ruby 3.3にはYJITとRJITという2つのJITコンパイラがあり、デフォルトでは無効になっていますが、それぞれ--yjitと--rjitで有効化できます。

Ruby on Rails では Ruby のオプションではなく、イニシャライザでYJITを有効にします。
この理由も説明されています。

> Ruby 3.3ではRubyコード内でRubyVM::YJIT.enableを呼び出すだけでYJITが有効化できるようになりました。
> 
> これを使ってYJITの起動を遅延させることで、アプリ初期化後は使われないコードのコンパイルを避けメモリ消費量を削減できます。Railsのイニシャライザから使うだけでも効果はあります



## JITとは

プログラミング言語を高速に実行するテクニックの一つです。
ChatGPTは次のように説明します。


> 「JITコンパイル」（Just-In-Timeコンパイル）は、プログラムを実行する直前にコードをコンパイル（翻訳）する技術です。通常のコンパイル手法と異なり、プログラム実行時にコードの一部を動的にコンパイルします。これにより、実行時のパフォーマンスが向上する可能性があります。
> 
> ### 原理
> - 動的コンパイル： プログラム実行中に必要に応じてコードを機械語に変換します。
> - 最適化： 実行時のデータや使用頻度の高いコードを分析し、最適化します。
> - 遅延コンパイル： 使用されるまでコードのコンパイルを遅らせることで、必要な部分のみをコンパイルし、リソースの節約につながります。
> 
> ### 効果
> - パフォーマンス向上： 実行時の情報を利用して最適化するため、パフォーマンスが向上することがあります。
> - プラットフォームの独立性： 中間言語を使用することで、異なるプラットフォーム間での互換性が高まります。
> 
> ### デメリット
> - 初回実行の遅延： コンパイルが実行時に行われるため、初回の実行が遅くなることがあります。
> - リソース消費： 実行時のコンパイルには追加のリソース（CPUやメモリ）が必要です。
> - 最適化の複雑さ： 効果的な最適化を行うためには高度な技術が必要です。
> 
> ### 実用例
> - Java Virtual Machine (JVM)： JavaのプログラムはJVM上で実行され、JITコンパイラによって最適化されます。
> - .NET Framework： Microsoftの.NET言語は中間言語で書かれ、実行時にJITコンパイルされます。
> - JavaScriptエンジン： 多くの現代のブラウザでは、JavaScriptコードはJITコンパイルを通じて高速化されます。
> 
> JITコンパイルは、実行時のパフォーマンス向上という大きなメリットがある一方で、初回実行の遅延や追加リソースの必要性などのデメリットも存在します。


## 感想

手動で動作確認をした感じでは、キビキビ動くようになった気がします。
しかし、JITが起動直後から効くとは思えません。プラシーボ効果だと思います。

## 参考

- [Rails + Ruby 3.3.0でYJITを使ってみる #Ruby - Qiita](https://qiita.com/miyamae/items/d707820e9b56c2026de1)
- [Ruby3.2+RailsでYJITを有効化 #Ruby - Qiita](https://qiita.com/takeyuichi/items/d1aaa441873ee3508343)
選択したフォルダのファイルリストを出力するバッチファイル

※ このバッチがあるフォルダに、FileList［yyyy-mm-dd］hhnnss.txt というファイル名で出力
※ 選択したフォルダのサブフォルダのファイルもリスト出力する

```bat:GetFileList.bat
@echo off

set yyyy=%date:~0,4%
set mm=%date:~5,2%
set dd=%date:~8,2%
set now=%time: =0%
set hhnnss=%now:~0,2%%now:~3,2%%now:~6,2%
set listFile=FileList［%yyyy%-%mm%-%dd%］%hhnnss%.txt

for %%f in (%*) do (
    dir /s /b "%%f" >> %listFile%
)

start %listFile%
```
履修証明プログラムなど受講歴の履歴書・職務経歴書への書き方が知りたい。

履修証明プログラムなどの各種講座の受講歴を履歴書のどう描くか考えてみました。

ググってみると

〇〇年〇月〇〇大学　履修証明プログラム　〇〇プログラム　入校
〇〇年〇月〇〇大学　履修証明プログラム　〇〇プログラム　修了

と書くことになっているようです。そして履修証明プログラムは学歴に書けるようです。

ここで疑問が生まれました

履修証明プログラムなどの入校時期って必須でしょうか？履修期間は各講座でまちまちで1年間の講座もありますし、半年や２か月半とかいろいろあります。よって受講期間ではなく全体で何時間取り組んだかが重要ではないかと思います。

よって履歴書には入校は入れずに

〇〇大学　履修証明プログラム　〇〇プログラム（〇〇時間）　修了　


と書けばよいのではと個人的に思います。それで何時間以上だったら自信をもって履歴書に書けますかという点について考えたことを記載します。履修証明プログラムは６０時間以上の講座が対象です。よってその８割以上である４８時間以上の講座なら自信をもって履歴書の書けるのではと個人的に思います。講座の受講だけでなく復習やアウトプットにどれだけ時間をかけたか面接で答えられるものを選んだ方がよいようですね。


科目等履修生、履修証明プログラム、公開講座、その他の受講歴を履歴書に書くかどうかは、以下の3つのポイントを軸に判断するのがおすすめです。

1. 応募先企業・職種との関連性

応募先企業・職種で活かせる知識やスキルを習得した場合は積極的に記載しましょう。
関連性が低い場合は、スペースの制約なども考慮し、厳選して記載しましょう。
関連性の判断に迷う場合は、企業のホームページや求人情報で求める人物像を確認しましょう。
2. 受講内容の質とレベル

有名大学や専門機関が実施するプログラム、難易度が高いプログラム、希少価値の高いプログラムは積極的に記載しましょう。
内容が具体的で、企業にアピールできるポイントがある場合は、詳細を記載しましょう。
受講内容を証明する資料（修了証書など）があれば、合わせて提出することを検討しましょう。
3. スペースと全体のバランス

履歴書全体の見栄えを考慮し、スペースが限られている場合は厳選して記載しましょう。
学歴や職歴など、他の項目とのバランスを意識しましょう。
記載する場合は、簡潔で分かりやすい文章で書きましょう。
具体的な判断基準

上記のポイントを踏まえ、以下の基準を参考にして判断しましょう。

積極的に記載する
・応募先企業・職種で必須となる知識やスキルを習得した
・有名大学や専門機関が実施するプログラムを受講した
・難易度が高いプログラムを受講した
・希少価値の高いプログラムを受講した
・受講内容を証明する資料がある

厳選して記載する
・応募先企業・職種で活かせる知識やスキルを習得した
・一定のレベルのプログラムを受講した
・スペースに余裕がある

記載しない
・応募先企業・職種との関連性が低い
・内容が薄いプログラムを受講した
・スペースがない

記載例

科目等履修生

2023年4月～2024年3月 ○○大学 ○○学部 ○○学科 科目等履修生として ○○科目 ○○科目 ○○科目 を履修

履修証明プログラム

2023年7月 ○○大学 ○○センター主催 ○○プログラム 受講
公開講座

2023年10月 ○○市生涯学習センター主催 ○○講座 受講

その他の受講歴

2022年5月 ○○株式会社主催 ○○研修 受講

注意点

受講内容を誇張したり、虚偽の内容を記載したりしないように注意しましょう。
略語や専門用語は避け、分かりやすい言葉で書きましょう。
誤字脱字がないように注意しましょう。

まとめ

科目等履修生、履修証明プログラム、公開講座、その他の受講歴は、応募先企業・職種との関連性、受講内容の質とレベル、スペースと全体のバランスを考慮して、厳選して記載することが大切です。

ここで一般的な話をします履歴書に書ける講座時間の明確な基準はありませんが、一般的には3時間以上の講座が履歴書に記載される目安とされています。

ただし、以下の要素も考慮する必要があります。

1. 講座の内容

仕事に直接関連する内容であれば、短時間でも記載を検討しましょう。
例えば、接客業であれば「接客マナー講座（2時間）」、事務職であれば「Excel操作講座（3時間）」などです。

2. 講座の主催者・講師

有名な企業や団体が主催する講座、著名な講師による講座は、短時間でも価値があると判断される可能性があります。

3. 講座の修了証・認定証

修了証や認定証を取得している場合は、講座内容の信頼性を高めることができます。

4. 応募する企業・職種

企業や職種によっては、短時間の講座でも評価される場合があります。
例えば、資格取得を必須条件としている場合は、その資格取得のための講座であれば短時間でも記載する価値があります。

5. 履歴書の全体のバランス

他の項目とのバランスを考慮し、スペースが許す範囲で記載しましょう。
多くの講座を記載するよりも、応募する企業・職種に関連性が高い講座を重点的に記載することをおすすめします。

具体的な記載例

2023年11月 ○○株式会社主催「ビジネスビジネスマナー講座（3時間）」受講
2023年12月 〇〇大学公開講座「Excel関数活用術（4時間）」修了
2024年1月 〇〇協会認定「秘書検定3級対策講座（20時間）」受講中

判断基準のまとめ

・3時間以上
・仕事に直接関連する内容
・有名な主催者・講師
・修了証・認定証
・応募先企業・職種
・履歴書の全体のバランス
上記の要素を参考に、履歴書に記載するかどうかを判断基準の参考にしていただければと思います。
記事を書く目的とネタの見つけ方を明確にしてみました

# ゴール
・エンジニアとして記事を書く目的、ネタの見つけ方を明確にする。

# 対象者
この記事は、書く目的、ネタを明確にしたい方。

# エンジニアが記事を書く目的(メリット)
## 学習の深化
学んだ内容をまとめることで、より深く理解することができます。
## 他人の役に立つ
自分の理解、解決法を提供することで、同じゴールを目指している方の参考になります。

# ネタの見つけ方
## 解決した課題
自分が解決した問題は、他の多くの人も同じようにインターネットで調べて解決しようとしています。だから、あなたの経験や知識を記事として共有すれば、その情報が他の人の役に立つことでしょう。
例えば、この記事自体が、私が技術記事を書く理由とネタをどのように見つけるかを明確にするために書いたものです。つまり、この記事は、私が自分自身で解決した課題に基づいています。

## 使いこなしたツール
ツールの公式ドキュメントは開発者によって作成されたものですので、最も信頼できる情報源です。
例えば、Linuxのlsコマンドのmanページは情報が豊富です。しかし、見慣れていない方には課題の解決に必要な情報を見つけるのが難しいです。
こういった場合、実用的な課題に基づく使い方を解説する記事が役立ちます。

# 世の中に同じ内容の記事があるとき
同じテーマの記事を書いている人はたくさんいますが、それぞれの経験に基づいた異なる視点があります。自分の経験を共有することで、他の人にとって価値あるものになる可能性があります。

# 終わり
記事を書くことは、自分の経験を振り返り、深く理解するための良い方法です。これからも、記事を書く意義を忘れたときには、この記事を読み返して、記事を書きたいと思います。
30代未経験でエンジニアになって思うこと

## はじめに

こういう系の記事好きじゃなかったので書くつもりもなかったのですが、ここ数日のXの投稿見たりやめ太郎さんの記事を見て勢いで書きました。

https://qiita.com/Yametaro/items/ea38e87fc28ff22ae44e

> こういう系の記事好きじゃなかったので

まぁじゃあ書くなよ的なことも思ったりしますが、
未経験に対する否定的な意見を見るとちょっと心が動くのもあるので勢いです。

### 前提として

30代で~~

とよく見ますが、33歳ぐらいまでです(感覚値)。
それ以降はもう実力つけて個人事業としていった方がいいと思います。

## 自己紹介

- 34歳
- 子供と妻と暮らしています
- 四国在住
- パチ屋に新卒で入社。30歳から学習開始して今に至る

### 補足

あとは自身の経験だけではなく

- 自分を頼ってくれてサポートした結果、エンジニアになれた人
- 自分を頼ってくれてアドバイスしたが、全く動かなかった人
- 自分を頼ってくれてアドバイスして動いたが、挫折した人
- 面接を通して対応した人

とざっくり10名ぐらいの方とも関わってきました。

## 良かったこと
4つほどあります。エンジニア特有というより総じて転職して良かったなと感じたことですね。

### 仕事が楽しい
僕は仕事が好きです。楽しい。基本的にずっと仕事してても苦ではないです。
パチンコ屋さんを退職した理由が「仕事が楽しいと感じる量が減ってきた(=成長が鈍化している自分に飽きてきた)」だったので、これが本当に良かった。

### ワークライフバランスが良い
家庭を持って初めて気付きましたが育児はすごく時間がかかる...
また、時間の総量だけではなく突発的なイベント(例: 風邪)も降ってくる。
多分パチンコ屋さんの時に子供授かってたら離婚してたと思います。

### 都会に対して良い関係が結べる
都会に住みたい!という人は転職を機に都会で暮らせる。
逆に年に数回ぐらいは都会に行きたいけど、あとは地方でゆっくり暮らしたい。
どちらでも選ぶことができます。

### 手に職がついた
これパチンコ屋さん時代に一番不安だったことなんですよね。
案の定28歳ぐらいの時に転職サイトに登録したらオファーが結構壊滅的でした。
今仮に会社が倒産してもなんとかなると思えるのは心理的にとても楽です。

## 悪かったこと

### 給料がガッツリ下がった
パチンコ屋さんが給料良すぎたのもあるんですが、比較すると年収が1/2になりました。(転職初年度の話)

### 家庭に負荷がかかる
学習期間中 ~ 入社後1年ぐらいはプライベートの時間を削らないとまぁ無理です。
お子さんとかいる家庭は結構厳しい印象。

### 最初の転職活動が辛い
まぁお祈りされるされる。
自己肯定感の下がり方がすごいですよ。この期間は。

## 今までの経験は役立つのか?

僕にはとても役立っています。
ただ、転職後1年ぐらいはあまり役立たないかも。

仕事でvalueを出す(=評価される)のって業界が変わっても同じ設計なんだなって思いました。
パチンコ屋さん時代と今で変わっているのは釘叩いているか、コード書いているかぐらいです。
あとは、パチンコ屋さんではマネジメントがメインだったので、転職後もマネジメント層にいるように心がけていたという点もあると思います。

## おすすめしますか?

好きにしたらいいと思います。ただ、背水の陣だけはおすすめしません。

自分に合わなかったら次~次~!!
ぐらいの感覚でチャレンジしたらいいと思います。途中で挫折しても学んだことは無駄にはならないので。
一応現実的な話をしておくと100人チャレンジしても数名しかなれません。多分。

## さいごに

駄文を読んでいただいてありがとうございました。
これからチャレンジされる方は頑張ってください☺️

### 戯言

> こういう系の記事好きじゃなかったので

特に有料で販売してるような(以下略
Pardot :  iframe


+ [iframeを利用した、フォームハンドラー連携について](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007VgH4h)

フォームハンドラーでは、ブラウザー側からの投稿 (通常の投稿方法) またはサーバー側からの投稿を実行できます。

 

https://help.salesforce.com/s/articleView?id=sf.pardot_considerations_for_using_form_handlers.htm&type=5

 

フォームハンドラーの送信がサーバサイドからの送信で実行される場合、ビジターの Cookie が削除されるため、ビジターアクティビティレコードは、関連付けられたプロスペクトレコードに結び付けられません。

 

https://help.salesforce.com/s/articleView?id=000383440&type=1

 

以下に非表示の iframe にデータを投稿すると同じようなことが議論されています。

この中で　クライアントのブラウザがリクエストを行うため、iframe がより適切に機能するのはこのためです。とあります。確実にクライアントからリクエストを行うためには、この方法が有効みたいです。

 

I tried a similar approach; I use $.post to POST form values to a PHP file. And there I use CURL (curl_exec) to post everything to the pardot form handler. Everything works fine but the Pardot cookies are not being set. Is the iFrame method a better method?

 

That's because you are doing a server side post. When you make the request from your server, Pardot sets the tracking cookies on your CURL's request. You want the cookies set on the client's browser. This is why the iframe works better, because the client browser is making the request.

 

Example of using a hidden iframe to pass data to a Pardot form handler before continuing with normal form submission.

https://gist.github.com/afischoff/6252964



+ [フォームとフォーム ハンドラー – 違いは何ですか?](https://qiita.com/Keiji_otsubo/items/fe8088d8ffa56f3b4b70)

簡単に言うと、フォームは Pardot 内で構築およびスタイル設定され、**iFrame** 経由で Web サイトに埋め込まれます。一方、フォームハンドラーはネイティブ Web サイトフォームの背後にある影のようなもので、データは Postscript 経由で Pardot に送信されると転送されます。フォームハンドラーを使用すると、フォームの構築とスタイル設定が Pardot の外部で管理されます。フォーム ハンドラーはデータのコピーのみを受信します。

たとえば、ページの URL または UTM パラメータ値を非表示のフォーム フィールドに渡すには Javascript を使用する必要があり、データを **iFrame** に渡すのが難しい場合があります。このため、JavaScript 要件をサポートできる開発者も必要になる場合があります。

+ [Google 広告と Pardot の間のコンバージョン数に関するデータの不一致](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007PzG5H)

:::note
This could be anything. The first thing I would investigate is if you've got duplicate tracking tags running that could cause a double-count. Sometimes this is due to do an iframe embedded form running duplicate tracking script, but ultimately it's a web developer issue. 

これは何でも構いません。最初に調査するのは、二重カウントを引き起こす可能性のある重複した追跡タグが実行されていないかどうかです。これは、iframe 埋め込みフォームが重複した追跡スクリプトを実行することが原因である場合もありますが、最終的には Web 開発者の問題です。 
:::


# サンクスページへのリダイレクト

+ [PardotフォームとZOOM連携実行時に、サンクスページにリダイレクトできません。](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000HDdwt)

:::note
下記ページに詳細が記載されています。

https://allmeetinghelp.com/how-to-use-zoom-webinar-for-pardot/
フォームを pardot ランディング ページまたは iFrame に埋め込む場合は、 ***target=“_parent”*** を追加します。

```
<form action="your post url" method="POST" name="hidden_form" target="_parent">
```
:::
ソフトウェアテストシリーズ 基礎知識編

# はじめに
実装と違い、テストを進んで取り組みたいと考える人は少ないと思います。筆者もテストが重要だということは理解していたものの、苦手意識があり、あまり手をつけていませんでした。今回はそれを克服すべく、勉強したことを書きましいた。

# ソフトウェアテスト技法とは
ある特定の条件下においてソフトウェアの振る舞いを記録し、それを期待される結果と比較・検証を行うプロセスのこと。開発者の意図した通りにプログラムが動くのか、いくつかのテストケースを用いて検証を行い、ソフトウェアの品質を保証するのが目的。ソフトウェアテスト技法とは、なるべく少ないテストケースでなるべく多くのバグを発見するための技術のこと。

# ソフトウェアテストの種類
- ユニットテスト : メソッド単位のテスト
- 結合テスト : メソッドの組み合わせのテスト
- UI/システムテスト : データベースやUI部品を組み合わせてテスト

# 重要な概念
ソフトウェアテスト技法には**網羅性とピンポイント**と**テスト設計アプローチ**という概念があります。
## 網羅性とピンポイント
網羅性とは、テストの漏れをなるべくなくすことで、ピンポイントとは怪しい部分を重点的に調べることです。ソフトウェアテストでなるべく多くのバグを発見するには、テスト技法によってテストの網羅性を確保しつつ、バグが潜んでいそうな部分やシステムの機能的に重要なところは、他に比べてテストケースを増やして調べる必要があります。

## テスト設計アプローチ
テスト設計アプローチには以下の2つがあります。
- 契約によるテスト
- 防御的テスト

契約によるテストとは、事前条件（渡される必要のある引数など、メソッドが正しく呼び出される際に満たすべき条件）の範囲内でテストを行うアプローチのことで、防御的テストとは、事前条件の範囲外もテストを行うアプローチです。
以下の例を見てみましょう。

```
fun test(n: Int) {
    return n * n * n
}
```
上記のメソッドは1~10までの整数しか渡されない（事前条件）と仕様で決まっていた場合、その範囲でしかテストを行わないものを契約によるテストと言い、上記のメソッドは1~10までの整数しか渡されないと仕様で決まっているが、その範囲外（文字列など）のテストも行い、例外やエラーが出ることを確認することを防御的テストと言います。

# 最後に
テスト技法はバグをなるべく多く発見するための手段であり、目的ではありません。正解はなく、大事なのはどういったアプローチを行うのか明確にすることで、これを意識していればテストの指針も明確になり、スムーズにテストが進められると思います。
OFFICE互換ツール「LibreOffice」をインストール

「Raspberry Pi400」を所有してます。「Raspbian OS」を使用しているですね。

## 「MSオフィス互換のソフト」である「LibreOffice」をインストール

LibreOfficeなるべく積極的に使いたいとのことで、脳ハックして上手く使いこなす方法です。

## usage

まずは「LibreOffice」の基本的な使い方を覚えましょう。
LibreOfficeの基本的な使い方が記載されています。

## official site love!

また、LibreOfficeの公式サイトには、LibreOfficeの機能や使い方について詳しく説明されています。
これらの情報を参考に、LibreOfficeを使いこなしてください。

## compatibility

また、LibreOfficeには、Microsoft Officeとの互換性があるため、Microsoft Officeで作成したファイルをLibreOfficeで開くことができます。

しかし、互換性があるとはいえ、完全に同じものではないため、注意が必要です。

LibreOfficeを使いこなすためには、練習あるのみです。
LibreOfficeを使って、様々なファイルを作成してみてください。
そして、LibreOfficeの機能を徐々に覚えていくことが大切です。

頑張ってください！💪

## 参考

- [ラズパイにOFFICE互換ツール「LibreOffice」をインストールする .... ](https://mugendennou.net/linux/raspi/raspiapplication/installlibreoffice/).
- [「libreoffice」無料のOffice系ソフトです！MS Officeとの互換性や .... ](https://briarpatch.co.jp/wakaruni/libreoffice/).
[EIP170] コントラクト作成時にサイズ制限を設ける提案を理解しよう！

# はじめに

初めまして。
**CryptoGames**というブロックチェーンゲーム企業でエンジニアをしている **cardene（かるでね）** です！
スマートコントラクトを書いたり、フロントエンド・バックエンド・インフラと幅広く触れています。

https://cryptogames.co.jp/

代表的なゲームは**クリプトスペルズ**というブロックチェーンゲームです。

https://cryptospells.jp/

今回は、コントラクト作成時に最大コードサイズを超えると、ガス不足でコントラクトの作成が失敗する新しいルール仕組みを提案している**EIP170**についてまとめていきます！

:::note info
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
:::

https://eips.ethereum.org/EIPS/eip-170

他にも様々なEIPについてまとめています。

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4

# パラメータ

| | |
| - | - |
| `MAX_CODE_SIZE` | `0x6000 (2**14 + 2**13)` |
| `FORK_BLKNUM` | `2,675,000` |
| `CHAIN_ID` | `1` (Mainnet) |

# 仕様

ブロックチェーンでは、各トランザクションが含まれるブロックには一意の番号（ブロック番号）が割り当てられています。
`FORK_BLKNUM`は、特定のブロックチェーンアップグレードやフォーク（分岐）が適用されるブロック番号を指します。
ここでは、`FORK_BLKNUM`は特定の変更が有効になるブロック番号を意味します。

コントラクトの作成とは、ブロックチェーン上に新しいスマートコントラクトをデプロイするプロセスのことです。
このプロセスは、初期化コードの実行を伴い、その結果としてコントラクトのバイトコードが生成されます。
`MAX_CODE_SIZE`は、ブロックチェーンにおけるスマートコントラクトのコードサイズの最大許容値を指します。
これは、ブロックチェーンのパフォーマンスやセキュリティを維持するために設けられた制限です。

したがって、`FORK_BLKNUM`以上のブロック番号でコントラクトが作成される時に、その初期化プロセスが`MAX_CODE_SIZE`バイトを超えるデータを返すと、コントラクトの作成は「**ガス不足**」のエラーで失敗します。
ガスは、ブロックチェーン上での操作（トランザクションの実行、コントラクトの作成など）に要する計算資源の単位です。
ガス不足のエラーは、トランザクションに割り当てられたガスが実行に必要な量を下回る場合に発生します。
この場合、コントラクトのコードサイズが大きすぎるため、その作成に必要なガス量が割り当て量を超え、結果としてトランザクションは失敗します。

# 補足

イーサリアムのシステムでは、スマートコントラクトが呼び出されるときに一定量のガス（ブロックチェーン上での操作に必要な計算資源の単位）が消費されますが、このプロセスは予想外の追加コストを発生させる可能性があります。
具体的には、コントラクトのコードをディスクから読み込む、仮想マシン（VM）での実行に向けてコードを前処理し、ブロックの正当性の証明に必要なマークル証明にデータを追加するという工程が、データの量に比例した（`O(n)`の）コストを引き起こす可能性があります。

このような二次的なコストは、現在のガスレベルでは許容されるかもしれませんが、将来的にガスの上限が動的に増加する可能性がある場合（これは実際に近い将来に起こり得ます）、より大きな問題となります。
これは、サービス拒否（DoS）攻撃ほど深刻な問題ではないにせよ、ブロックチェーンの有効性や無効性を証明するための証拠を検証するライトクライアント（ブロックチェーンの全データをダウンロードせずに済む軽量クライアント）にとって都合が悪いです。

この問題に対処するための提案された解決策は、ブロックチェーンに保存できるオブジェクトのサイズに上限を設けることです。
この上限は現在のガスリミットで実現可能なサイズをわずかに上回る値に設定することで、システムに悪影響を与えずに実装できます。
これにより、将来的にガスリミットが増加したとしても、スマートコントラクトのサイズが無制限に大きくなることを防ぎ、関連するコストの増加やシステムの脆弱性を事前に抑制することが期待されます。

# 参考

- [**EIP-170**](issue and discussion: https://github.com/ethereum/EIPs/issues/170)
- [**pyethereum implementation**](https://github.com/ethereum/pyethereum/blob/5217294871283d8dc4fb3ca9d8a78c7d416490e8/ethereum/messages.py#L397)

# 引用

Vitalik Buterin (@vbuterin), "EIP-170: Contract code size limit," Ethereum Improvement Proposals, no. 170, November 2016. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-170.

# 最後に

今回は「コントラクト作成時に最大コードサイズを超えると、ガス不足でコントラクトの作成が失敗する新しいルール仕組みを提案している**EIP170**」についてまとめてきました！
いかがだったでしょうか？

質問などがある方は以下のTwitterのDMなどからお気軽に質問してください！

[Twitter @cardene777](https://twitter.com/cardene777)

他の媒体でも情報発信しているのでぜひ他も見ていってください！

https://chaldene.net/

https://zenn.dev/heku

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4