OmniAICreator/Qiita-1.07M huggingface dataset:
has_many :through メモ

`has_many :through` は、Railsにおけるリレーションシップ（関連付け）を表現するための強力な方法の1つです。これを理解するために、まず2つのモデル間の基本的な関連付けを考えてみましょう。例として、ブログアプリケーションを考えます。

1. `User` モデル（ユーザー）
2. `Post` モデル（投稿）

これらの2つのモデルは、一般的な「ユーザーが投稿を作成する」というリレーションシップを持っています。通常、ユーザーは多くの投稿を作成し、各投稿は特定のユーザーに関連付けられています。これを `User` モデルと `Post` モデルの関連付けで表現できます。

```ruby
# user.rb
class User < ApplicationRecord
  has_many :posts
end

# post.rb
class Post < ApplicationRecord
  belongs_to :user
end
```

これにより、ユーザーは多くの投稿を持つことができ、各投稿は特定のユーザーに関連付けられます。

しかし、ブログアプリケーションにはもう1つの要素があります：コメント。ユーザーは投稿にコメントを追加できます。しかし、これは少し複雑です。1つの方法は、`Comment` モデルを作成し、各コメントが特定の投稿に関連付けられていることを表現することです。しかし、`Comment` モデルだけでこれを実現しようとすると、どのユーザーがどのコメントを投稿したのかを追跡することが難しくなります。

ここで `has_many :through` 関連付けが登場します。これを使って、中間テーブルを介してリレーションシップを作成します。例として、`Comment` モデルを導入し、`User`、`Post`、および `Comment` の関連付けを構築してみましょう。

1. `User` モデル（ユーザー）

```ruby
class User < ApplicationRecord
  has_many :comments
  has_many :posts
end
```

2. `Post` モデル（投稿）

```ruby
class Post < ApplicationRecord
  belongs_to :user
  has_many :comments
end
```

3. `Comment` モデル（コメント）

```ruby
class Comment < ApplicationRecord
  belongs_to :user
  belongs_to :post
end
```

ここで `Comment` モデルは、`User` と `Post` モデルの両方に関連付けられています。これにより、ユーザーがどのコメントを投稿し、どの投稿にコメントを追加したかが追跡できるようになります。

さて、この関連付けを活用することで、例えば特定のユーザーがどの投稿にコメントしたかを知ることができるようになります。これは `has_many :through` の力です。中間テーブルである `Comment` モデルを介して、ユーザー、投稿、コメントを簡単に関連付けることができます。このように、`has_many :through` 関連付けは、複雑な多対多のリレーションシップを実現するのに非常に便利です。

使用例
`has_many :through` 関連付けの実際の使用例を示します。前述の例に基づいて、ユーザー、投稿、コメントの関連付けを使ってみましょう。

1. ユーザー（`User` モデル）が投稿（`Post` モデル）にコメント（`Comment` モデル）を追加する場合、これは `User` から `Comment` を通じて `Post` にアクセスするリレーションシップを作成します。以下が具体的な使用例です。

```ruby
# ユーザーがコメントを追加
user = User.first
post = Post.first

comment = Comment.new(content: "素晴らしい投稿です！", user: user, post: post)
comment.save
```

2. ユーザーが自分のコメントを取得したり、ユーザーがどの投稿にコメントを追加したかを知るために、`has_many :through` を使用できます。

```ruby
# ユーザーがコメントした投稿の一覧を取得
user = User.first
posts_with_comments = user.posts

# 特定の投稿に対するコメントを取得
post = Post.first
comments = post.comments

# ユーザーがどの投稿にコメントしたかを知る
user = User.first
posts_with_comments = user.posts
```

3. `has_many :through` を使うことで、多対多のリレーションシップも簡単に扱えます。例えば、`has_many :through` を使用して、ユーザーが「いいね！」をした投稿をトラッキングする場合もあります。 `Like` モデルを導入し、`User` と `Post` モデルを介して「いいね！」の関連付けを行うことができます。

```ruby
# User モデル
class User < ApplicationRecord
  has_many :likes
  has_many :liked_posts, through: :likes, source: :post
end

# Post モデル
class Post < ApplicationRecord
  has_many :likes
  has_many :liked_by_users, through: :likes, source: :user
end

# Like モデル
class Like < ApplicationRecord
  belongs_to :user
  belongs_to :post
end
```

これにより、ユーザーが「いいね！」をした投稿と、特定の投稿に「いいね！」をしたユーザーを取得できます。 `has_many :through` を使用することで、多対多のリレーションシップを扱うのが簡単になります。

使用例にはさまざまなケースがあり、これは便利な関連付けの方法で、データベース内のリレーションシップを効果的に管理するのに役立ちます。
【Jenkins】GitHub連携②

## はじめに
今回やること
　・リモートブランチにコミットされたことを検知したら、ローカルブランチにPullするShellを作成

### GitHub連携
* GitHubのアクセストークンをJenkinsに登録
GitHub側でトークンを生成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689436/ec9c18d6-3d71-9db6-2866-05bb2af2d425.png)
生成したトークンをJenkinsのcredentialsに登録する。（ユーザーIDとパスワード）
※パスワードにアクセストークンを入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689436/95eda133-3e4b-23ee-1a43-d12846b20384.png)
* JenkinsのAPIトークンを生成
開発者⇒ユーザーを選択⇒設定からAPIトークンを生成します。トークンの名前は何でも良いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689436/64e8ec05-1a54-a32f-4f0f-ddb53c662a23.png)

* Webhooksの設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689436/ed3487e0-6ebd-a874-0da7-f3d5516bcd3e.png)

Payload URLは↓以下のように設定します。
```http://[Jenkinsのユーザー名]:[JenkinsのAPIトークン]@[サーバのIPアドレス:ポート]/job/[Jenkinsのジョブの名前]/buildWithParameters?token=[JenkinsのAPIトークンの名前]```
「Add webhook」で登録します。

* ジョブの作成
新規ジョブの作成⇒フリースタイル・プロジェクトのビルドでジョブの内容を決めていきます。
GitHub projectにチェックを入れます。
Project urlにはリモートリポジトリのURLを入力します。（例：https://github.com/××/××.git）
ビルドのパラメータ化にチェックを入れて、名前にはpayloadと入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689436/cb7de9a9-f911-dbfd-9260-c98539bbaa08.png)

ソースコードの管理ではGitにチェックを入れて、リポジトリURLを入れます。
※Project urlと同じで良いです。
認証情報では、GitHubのアクセストークンを、セレクトボックスから選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689436/8c32b5ca-ab01-5ed8-a203-da2b8d0dd7dc.png)
ブランチの名前は適宜変えてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689436/1f921c87-e881-3551-1454-4def3fe7767f.png)

認証トークンにはJenkinsのAPIトークンの名前を入れてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689436/157f5b37-b455-614f-2426-d38a15f65d05.png)

ビルド環境のリモートホストでシェルを実行にチェックを入れ、SSHサイトでは登録しているIPアドレスを選択します。
ビルド前スクリプトには、ローカルリポジトリの場所に移動して「git pull」をするshellを書きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689436/ba07826b-3786-aaab-0795-638269dcdf5b.png)

最後に保存を押します。

【Jenkins】GitHub連携①：https://qiita.com/mojapico/items/9c114f0890adaf3a0862
【Jenkins】GitHub連携①

## はじめに
今回やること
　・Jenkinsのインストール
　・JenkinsからSSHでサーバにアクセス

### Jenkinsのインストール（今回はCentOS）
* Javaをインストール
 　※既にインストール済みであればスキップしてください。
$```sudo yum install -y java-11-openjdk-devel.x86_64```
* Jenkins公式yumリポジトリの追加
 　※既にインストール済みであればスキップしてください。
$```curl -o /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo```
$```rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key```

* Jenkinsのインストール
$```yum -y install jenkins```
サーバ起動時の自動起動の設定
$```systemctl enable jenkins```
Jenkinsの起動
$```systemctl start jenkins```

* Jenkinsの起動
デフォルトの設定だと、```http://IPアドレス:8080/```でログイン画面が開きます。
$```vim /var/lib/jenkins/secrets/initialAdminPassword```でパスワードファイルを開いて、
パスワードをコピーします。
Jenkinsの画面に戻ってパスワードを入力してログインします。

### JenkinsからSSHでサーバにアクセス

* SSHのプラグインをインストール
Jenkinsの管理⇒Pluginsの画面に移動します。
Available pluginsを選択して、検索フォームに「SSH」と入力してインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689436/a9ad6789-1938-f630-7610-e1a3fb9aff79.png)

* 認証情報の登録
Jenkinsの管理⇒Credentialsの画面に移動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689436/eef232a3-1bae-d9c5-4108-38af00d8e6dd.png)
Domeinsのリンクをクリックしてグローバルドメインの画面に遷移します。
「+ Add Credentials」でユーザー名とパスワードを登録します。（サーバのログインIDとパスワード）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689436/47fa92cb-00dc-39dd-01c3-979c8f9499ce.png)
* ジョブ作成
「+ 新規ジョブ作成」を選択してジョブ名を入力し、「フリースタイル・プロジェクトのビルド」を選択する。
項目がたくさんありますが、ひとまず、SSH接続を確認したいだけなので、ビルド環境の設定のみ行います。
「リモートホストでシェルを実行」をチェックしてIPアドレスと適当なスクリプトを書きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689436/91e42aae-58e9-9a81-11a0-3744c503b40f.png)
shellはなんでも良いです。↓
```shell
echo "test"
```
最後に適用⇒保存をします。
ダッシュボードに戻ると今作成したQiitaというジョブが作成されています。
右にある実行ボタンを押してみましょう。実行の履歴が見れると思うので確認してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689436/b6fd747e-8086-b378-9944-2616e06cee49.png)

【Jenkins】GitHub連携②：https://qiita.com/mojapico/items/ce475d827551b739ab3f
エンジニアなのに全銀システムを知らないのでざっと調べてみた

# はじめに
10/10、3連休明けの火曜日にとあるニュースが話題になりました。

https://www.nikkei.com/article/DGXZQOUB101ZQ0Q3A011C2000000/

全銀システムと呼ばれるシステムで他行あての振込ができない障害が発生しました。

結果として障害発生の約2日後の10/12に復旧が発表されました。

https://www.nikkei.com/article/DGXZQOUB11C3L0R11C23A0000000/

ネットニュースでも大々的に報じられていたので、ニュースは随時チェックはしていました。
しかし大学卒業後5年間IT企業でエンジニアをしていながら全銀システムが具体的にどういうシステムなのかがわかりませんでした。
<br>
<br>
今回は全銀システムについて簡単にまとめてみました。

# 全銀システムとは

>｢全国銀行データ通信システム｣、通称「全銀システム」は、全国銀行内国為替制度に加盟する銀行間の内国為替取引に関する通知の送受信、および当該取引によって生じる銀行間の為替決済額の算出・清算などを集中的に行うオンラインシステムのこと

引用元：[全銀システムとは](https://www.zengin-net.jp/zengin_system/)

聞いたことない日本語が連なっていますね・・・。
**内国為替**とは郵便振替や銀行振り込みなど、人や物が現金実物を別の銀行へ運ばず、遠隔の人とお金のやり取りをすることです。

つまり全銀システムとは
全国銀行内国為替制度に加盟する銀行同士の取引通知の送受信、またその取引で動く金額の算出・清算を中心的におこなうオンラインシステムということです。

## 全国銀行内国為替制度に加盟する銀行

https://www.zenginkyo.or.jp/abstract/outline/organization/member-01/

https://www.zengin-net.jp/zengin_system/member/

こちらに加盟銀行の一覧が掲載されています。
見たところ、メガバンクはもちろん、地銀やネット銀行などほとんどの銀行が加盟しています。

# いつから稼働したのか？

>1973年の稼動開始以来、運用時間中にオンライン取引を停止したことがない安全性・信頼性、国内のほぼ全ての金融機関が参加している広範なネットワークにもとづく利便性、稼動開始当初から世界に先駆けて即時入金を実現した先進性が挙げられます。

引用元：[全銀システムとは](https://www.zengin-net.jp/zengin_system/)

全銀ネットの公式によると半世紀前から使用されているシステムですね。

私が仕事で携わった中で最も古いものでも5年くらいのシステムなので、かなりの歴史があるのだと思いました。

# 誰が使ったのか？
Qiitaで紹介されるような個人開発で作ったものでは当然ありません。

誰が（どこのベンダー）この巨大でミッションクリティカルなシステムを作ったのか気になりました。

https://xtech.nikkei.com/atcl/nxt/news/18/16078/

https://www.businessinsider.jp/post-276648

これらの記事を見る限り**NTTデータ**のようですね。
日本銀行も関わるシステムですからNTTデータだろうなとは思っていましたが、これほど多方面へ影響があるシステムを作れるのはさすがトップベンダーだなと思いました。

# さいごに
報道を受けて全銀システムについて調べてみました。
障害復旧にあたったベンダー、エンジニア、銀行関係者の皆様、お疲れ様でした。
対応ありがとうございました。
森羅万象プロジェクト　Chapter00-01:自己紹介！！

**こんにちは！森羅万象プロジェクトです！（どーん！！）**  
    
いきなり「森羅万象プロジェクト」と言われても、なにがなんだかわからないと思いますので、  
  
初回は、  
**1.森羅万象プロジェクトとは？？  
2.メンバー紹介  
3.結局何をするプロジェクトなの？？**  
を話したいと思います。  
  

# 1. 森羅万象プロジェクトとは？？  
・このプロジェクトは「[セキュリティ・キャンプ全国大会2023](https://www.ipa.go.jp/jinzai/security-camp/about.html)」内のグループワークで、  
  
**「なんでもかんでも自分で作れたら最強なのでは！？」**  
  
という一言から生まれたものです。  
(確か)森羅万象という名前もそこから来ています。  
  
  
# 2. メンバー紹介  
(Astalisks個人の主観、セキュリティ・キャンプでの印象を含みます)  
(2024/12月現在：6人になりました！！)  
  
**Astalisks**  
・今年社会人になって東京にきました。  
・AI、UX、データ分析、クラウド、ネットワークを浅く勉強。  
・CPUやOSを作ろうなんてそれまで思ったこともなかった。  
・プロジェクトの復習がてら記事づくりのメイン担当に。  
[Xのリンク](https://twitter.com/Astalisks_ITEVG)  
    
**Kyuta**  
・関西の高校3年。  
・無線工学の勉強中。ギターのエフェクタ作れる。  
・[CTF(Capture The Flag)](https://cybersecurity-jp.com/column/33780)始めたらしい。あと能楽もできる。  
・キャンプでバス移動の際に寝坊したとかしてないとか。(間に合ったらしいとか。)  
[Xのリンク](https://twitter.com/Ky00Ge)  
  
**shinbunbun**  
・東北の大学4年。  
・[Cybozu labyouth](https://labs.cybozu.co.jp/youth.html)、[LINE API Expert](https://www.line-community.me/ja/apiexpert/request)、Rust愛好家。  
・キャンプではバックエンドのみの課題を瞬殺してフロントまで作ってた。(すごい。)  
・めっちゃお酒つよい、くわしい。  
[Xのリンク](https://twitter.com/shinbunbun_)  
  
**wakuto**  
・中国・四国の大学4年。高専出身。  
・[SecHack365](https://sechack365.nict.go.jp/)、なんとこのキャンプ2回目。  
・CPU作れる。C/C++やRust、Verilogできる。  
・キャンプのバス時間で質問やお悩み相談をしたら、耳寄りな情報をいくつも教えてくれた。(ありがとう。)  
[Xのリンク](https://twitter.com/otukaw)  
  
**yn0014**  
・関東の大学院1年。高専出身。  
・DSL(ドメイン固有言語)の研究をしている。C言語の分かるCPUを開発している。  
・[SecHack365](https://sechack365.nict.go.jp/)、[(IPAの)未踏(事業)](https://www.ipa.go.jp/jinzai/mitou/mitou2023/)、[IPAの国家試験](https://www.ipa.go.jp/shiken/kubun/list.html)6つも受かってる。  
・キャンプでは隣のゼミだったので、遊びに行ったら私が分かるまで細かく説明してくれた。(ありがとう。)  
[Xのリンク](https://twitter.com/yn0014)  
  
**koonato**  
・24.07～　加入！ 　wakutoさんの後輩。  
・OSが書ける。キャンプでは[mikanOS](https://github.com/uchan-nos/mikanos)にネットワークを実装したそう。  
・友達から「なんでも屋」と呼ばれるほどなんでもできるらしい。  
・いきなりモブプログラミングで私の100倍の速さでRust書いててびっくり。
  
# 3.結局何をするプロジェクトなの？？  
  
我々が立てた目標はズバリ、  
**「CPUもOSもアプリも、作れるものは全部自作する！！」**  
です。  
  
セキュリティキャンプではそれぞれ別のゼミを受講し、別々のものを制作していました。  
CPUを部品のはんだ付けから作った人もいれば、デバイス間の通信の方法を1から考えたり、  
あるいはめっちゃデータの消えにくいシステムを作った人も、、。  
  
しかしグループワークで専門の異なるメンバーが集まると、  
**得意を活かして創作に貢献できる！  
作った経験がなくても先駆者が身近にいる！！**  
という安心感が個人的にはありました。  
  
どこまで作れるか、いつまでやるかは分かりませんが、進捗を温かい目で見守っていただけますと幸いです。  
将来的には制作したものを誰もが真似して作れるように改良し、マニュアルとしてお届けできたらと考えています！！  
  
またこのような機会を用意していただける**セキュリティ・キャンプ**に  
皆さんもぜひ応募してみてください！！  
[IPAのセキュリティ・キャンプ紹介ページ](https://www.ipa.go.jp/jinzai/security-camp/about.html)  
  
  
次の記事は[「00-02_自作の「レベル」とは」](https://qiita.com/shinrabansyoProject/items/2a9b00401d6e08b83478)
「プロになるためのWeb技術入門」を読んでWeb技術についてまとめてみた

# はじめに
表題の本を読んで、Web技術に関して簡単にまとめてみました。


## プロトコル（Protocol）
_情報をやりとりするための決まり事などのこと。_

### 具体的には

さまざまな通信においてそれぞれに決まり事があり、
例えば、

- HTTP（Hyper Text Transfer Protocol：HTMLをやりとりするためのプロトコル）
- SMTP（Simple Mail Transfer Protocol：メール送信のためのプロトコル）

などがある。

## リクエスト（Request）
_Webクライアント（Webページを閲覧する人や、Webサービスを利用する人など、利用者を指す）からWebサーバへ通信を行う際に投げる要求のこと。_

### 具体的には
HTTP通信を例とすると、
WebクライアントがWebサーバに「〇〇のページをください」と要求すること。

## レスポンス（Response）
_Webクライアントから来たリクエストに対する応答のこと。_

### 具体的には
HTTP通信を例とすると、
Webクライアントの「〇〇のページをください」の要求に対して、
「〇〇のページ」のHTMLを返すこと。

## ステートフル（stateful）
 _意味は「状態を持つ」。_

### 具体的には
通信のやり取りにおいて、やり取りが終了するまで情報を保持している状態を指す。一連のやり取りの情報を持っているため、現在ログインしているか、などのの情報を持ちつつ、リクエストとレスポンスのやり取りを行うことができる。

## ステートレス（stateless）
_意味は「状態を持たない」。_

### 具体的には
通信のやり取りにおいて、1回のみのやり取りで完結する。1回限りの送受信で完結するため、前後でどのようなやり取りをしていたか、といった情報を持つことができない。リクエストとレスポンスは常に1回の往復で完結するため、それまでの情報は後に続かない。

:::note
HTTP通信はWebクライアントとWebサーバのやり取りを、常にステートレスな状態で行う。
:::

_Webクライアント　→リクエスト→　Webサーバ_

_Webクライアント　←レスポンス←　Webサーバ_

上記の1往復で通信が完結するため、繰り返しても前後にどのような状態か、といった情報を後に持ち越すことはできない。

## クッキー（Cookie）
_HTTP通信において、ステートフルな状態を実現させるための技術。_

### 具体的には
__【例】Webブラウザからとあるサービスにログインをする__

WebブラウザはHTTPリクエストをWebサーバに投げる。Webサーバからのレスポンスではログイン後のページを返す。

前述の通り、ステートレスでは情報を持たないため、Webサーバがクッキーに情報を含めて、Webクライアントにレスポンスを返す。

次にWebクライアントがWebサーバから受け取ったクッキーを保持したまま、Webサーバにリクエストを投げる。
すると、Webサーバ側でクッキーに含まれる情報から個人を特定することができる。

:::note warn
クッキーに情報をそのまま含めてやり取りを行うことは、セキュリティの観点からよろしくない。
そのため、WebサーバがセッションIDなどを発行してクッキーに含めてレスポンスを返し、セッションIDを保持したままやり取りを行うことが一般的。
WebサーバはセッションIDから個人の特定を行えるように情報を保持している。
:::

# ポート番号（Port）
_アプリケーションを識別するための番号。_

### 具体的には

IPアドレスでは通信するコンピュータまでは特定ができるが、1台のコンピュータ内で複数のアプリケーションが稼働していると、どのアプリケーションに情報を渡せば良いかわからなくなる。

これを防止するため、ポート番号を利用してアプリケーションの特定を行い、情報を渡す。

:::note warn

上記の理由から異なるアプリケーションでポート番号が被ることはNGとなる

:::

# 最後に
Web技術についてわかりやすく解説されており、とても理解しやすい内容でした。記事を書きながら理解が足りていない箇所を調べたり、読み直したりしたことでより理解が深まったと感じています。
タイトルに入門とあるだけあって、初学者の方におすすめの内容です。
scalpel

<!--2023/10/13-->
[picoCTF][Forensics][Matryoshka doll]
## Writeup
* まずは基本のfileコマンドから実行。pngの画像っぽい。
![file.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/07d1d07c-ee5b-a1fa-4cd3-6d054f423005.png)
<br>

* 問題のタイトルから、なんかファイルが隠れていそう。
バイナリエディタで確認したけど、何もわからん・・・。
[-n]を付けないと、見づらい・・・。
[-r]は上書き防止。
~~~bash
hexeditor -n -r dolls.jpg
~~~
<br>

* ファイル内のファイルを検索できるツールがあるようです。
とりあえず実行すると、設定ファイルを見なさいと。
言われるがまま、設定ファイルを確認。
あー、そういうことね、といった感じの設定ファイルだった。
~~~bash
sudo vim /etc/scalpel/scalpel.conf
~~~
<br>

* zipとpdf、jpgあたりを検索することにした。
不要なフォルダを消して、実行。
~~~bash
rm -r scalpel-output 
scalpel dolls.jpg
~~~
<br>

* そんで実行。zipファイルが出力された。
unzipコマンドでは上手くいかなかったけど、
Engrampa Archive Manager（GUIのデフォルト）なら、無事に解凍できた。
画像を確認したけど、途中で切れちゃってる。
<br>

* ファイルの途中でzipの末尾と判断されている気がしたので、
ファイルの末尾までzipファイルと判断されるように設定ファイルに追記。
無事に画像が確認できた。
<br>

* とりあえず問題のタイトルに従って、繰り返し。
~~~conf:/etc/scalpel/scalpel.confの抜粋
#---------------------------------------------------------------------
# MISCELLANEOUS
#---------------------------------------------------------------------
#
        zip     y       10000000        PK\x03\x04      \x3c\xac
        zip     y       10000000        PK\x03\x04      \x97\xc8\x05
        zip     y       10000000        PK\x03\x04      \x1a\xfe\x02
        zip     y       10000000        PK\x03\x04      \xa2\x2f\x01
        zip     y       10000000        PK\x03\x04      \x01\x00\x4e\x00\x00\x00\x82
#
#       java    y       1000000         \xca\xfe\xba\xbe
~~~
<br>

* 無事にflag.txtを入手できた。
catコマンドすると、いい感じ。
![answer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/ccf4da7e-7a4d-596b-9036-f638ed151778.png)
<br>

* 以上です。
それでも DNCL 向けの学習環境を作る

　情報Iで出題される擬似言語 (以下 DNCL) を、[ブロックを使って学ぶための環境](https://capg.app/) を実装しました。Web ブラウザ内で完結できるように、Vue + Vuetify -> [Blockly](https://developers.google.com/blockly) -> Calcium (後述) -> [Pyodide](https://pyodide.org/en/stable/) という構成になっています。全体像を下図に示します。
![学習環境の構成図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3572748/d23b5ef9-fc3f-63b2-b614-c0cdac69351c.jpeg)



## Blockly を埋め込む

### Vue + Blockly とした理由
　[Lit](https://lit.dev/) をはじめ `shadowDom` 内では [Blockly エディタを読み込むことができない](https://github.com/google/blockly/issues/1114) ようです。
　このため Vue についても、component 化はできないことがわかりました。本当はライブラリとして利用できるようにしたかったのですが...。App.vue などのトップレベル直下であれば `Blockly.inject()` できます。ただこれも Vue のバージョンを上げた際に動作しないことがありました（2024/08/21 現在使っているのは v3.2.25）。

### renderer に `zelos`を指定すると Scratch 風になる
　デフォルトの renderer では、パズルのピースのような形になります。これを [Scratch](https://scratch.mit.edu/) に近づけることができます。

```javascript
const workspace = Blockly.inject(document.querySelector('#div-blockly'), {
    renderer: 'zelos',
    ...
  })
```

`Blockly.inject()` に上記を指定すると大分見た目が変わり、今の子どもたちにもなじみ深いブロックの形になると思います。

### generator から DNCL, Calcium それぞれのコードを生成する
　Blockly にはブロックで組み立てたプログラムを何らかの言語として生成するための generator が組み込まれています。JavaScript などのコードを生成することもできますが、やや不自然なコードになります。不自然というのは、普段のテキストプログラミングとは異なるお作法になる、という意味です。
　generator は自分で追加することが可能です。今回は新たに2つ実装することになりました。1つは DNCL 向けの日本語表現を生成するものです。もう1つは Calcium で実行するための JSON 配列を出力します。


## Calcium + Pyodide

### Calcium とは
　本プログラミング環境の内部で利用しているインタプリタです。入力として JSON 配列を受け取ることが特徴です。なぜ [Calcium](https://pypi.org/project/calciumlang/) を使っているかというと、Blockly と相性が良いためです。Blockly はブロックをテキスト（コード）に変換するための環境と言えますが、実行環境は付属していません。Calcium は Python 上で動作し、行単位で実行することができます。Calcium の1行は1つのブロックと対応関係があり、generator から生成したコードをそのまま入力として利用可能です。

### Pyodide を `WebWorker` 内で実行する
　[公式サイト](https://pyodide.org/en/stable/usage/webworker.html)を参考に実装し、プログラム自体が無限ループの時でも、ページごと固まらないようにしました。

### 外部ライブラリを `micropip` で読み込む
　Calcium インタプリタを読み込むためには[`micropip` モジュール](https://micropip.pyodide.org/en/v0.2.2/project/api.html#micropip.install)を最初に `import` しておく必要がありました。

```javascript
const pyodide = await loadPyodide()
await pyodide.loadPackage(['micropip'])
pyodide.runPython(`import micropip
await micropip.install('calciumlang')
from calciumlang.runtime import Runtime
`)
```

## 最後に

### Scratch から Python へ...
　Scratch から次のステップへ進むための学習環境を目指して、DNCL でプログラムを表示できるようにしました。また、ブロックの中には日本語表現だけでなく Python の文法に則ったものもあります。これらは互いに等価なコードを出力するため、ブロックプログラミングからテキストプログラミングへ移行する際に比較しながら使えるのではないかと考えています。

　[こちらのページ](https://capg.app/)で、実際に試すことができます。また本環境は[ソースコード](https://github.com/0xCAF2/calcium-editor)を公開しています。少しでも興味を持っていただけたら嬉しいです。
【AWS】日次バッチの異常発生をSlack通知で検知する【運用監視】

## はじめに
### 日次バッチの異常発生通知がないと困ること
深夜の日次のバッチ処理をAWSのStepFunctionsなどで実行している場合、手動実行の結果確認と異なりバッチ実行結果の確認が翌日の朝になります。また、毎日実行されているバッチが連日正常に終了していると気が付かぬうちにある日異常が発生し、以降連日気が付かない状態で異常が発生し続けるという困ったことが起こります。
システム運用のあるべき姿として異常が発生したらすぐに通知すべき。その時寝ていて気が付かなくても翌日の業務開始時に異常発生を運用者が知り、すぐに対応できるようにしておきたいところです。
システム運用のチームではSlack等のチャットツールが良く使われていると思うが、そこにメッセージ通知するためのシステム構成を記事にました。
※この記事はアーキテクチャの説明をメインにしています。コンソール画面を使った設定手順等は各サービスのコンソール画面の指示に従ってください(操作手順を説明されているAWS公式サイトのURLをこの記事の最後に記載してあります)

## 使うAWSサービス
・Amazon CloudWatch
・Amazon SNS
・AWS Chatbot

## アーキテクチャ図
![ChatBot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/86b289a6-615f-f20f-bcfa-b16e57a175f9.png)




## アーキテクチャ説明
1．AWS Stepfunctions ステートマシン
・日次バッチ
・このステートマシンで発生したエラーをCloudWatchLogsに登録させる設定をしておく
<設定手順>
①StepFunctionsでエラー発生時にFailStateに状態が遷移するようにフローを設定する
![Sfn1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/52cc864e-dcdd-639d-5c8f-5cfcbf86986c.png)
②StepFunctionsの設定でCloudWatchにエラーログが登録されるように設定する
![Sfn2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/c600a2dc-ec26-5223-9b67-0ab58753c9bd.png)

2．Amazon CloudWatch Logs（Cloudwatch アラーム)
・CloudwatchLogsにステートマシンで発生したエラーログが登録される
・エラーログが登録を条件にSNSに通知するCloudWatchAlarm設定しておく
※通知先の設定にSNSトピックの選択が必要になります。事前にSNSトピックの設定が必要です。

3．Amazon SNS
・CloudWatchアラームからの通知を受け取る
・SNSトピックはAWS Chatbotへ送る

4．AWS Chatbot
・Slackチャンネルを指定してChatbotからメッセージを送信する
※Slack通知を行うSlackチャンネルはエラー通知専用のチャンネルを用意しておいたほうがメッセージが他メッセージによって流れないので良いかも
※メッセージの形式はあまり凝らずにとにかく「何が」「いつ」エラーを出したかだけ通知できるようにすることが重要


## さいごに
・Slackのメッセージにはエラーの詳細を書く必要はないと思います。とにかく「どの名前のサービスで」「いつ」エラーが発生したかさえ知ることが重要。
・深夜バッチは意外な原因でいつの間にかエラーを投げるようになるので、ChatBotを使っていつでも気が付ける状態は油断せず作っておきましょう

## 各サービスの詳しい説明(AWS公式ページへのリンク)
・Amazon CloudWatch
(CloudWatch アラームでのモニタリング)
https://docs.aws.amazon.com/ja_jp/autoscaling/application/userguide/cloudwatch-alarm-notifications.html
・Amazon SNS
(SNSトピックを作成する)
https://docs.aws.amazon.com/ja_jp/sns/latest/dg/sns-create-topic.html
・AWS Chatbot
(通知と AWS Chatbot との統合の設定)
https://docs.aws.amazon.com/ja_jp/dtconsole/latest/userguide/notifications-chatbot.html
Django基本３～URLに年を入力すると和暦を返す画面を表示してみよう。できるかな？(・・;)

こんにちは。

前回より少し成長したviewをつくってみたいとおもいます。

■やりたい事
　　URLの最後に年４桁（西暦）を入力してブラウザーを入力すると、
　　該当する和暦を返す画面をこさえる。

■開発準備
　　今回様にプロジェクト作成、初期DBのマイグレーション,APP作成を行います。
　　プロジェクト名：norizo_project2
    アプリケーション名；norizo_app2
    やり方は以下をご参照ください
　　　https://qiita.com/norizo_no1/items/bd3bf8248084ee2975af

1.URLのディスパッチ
　　URLに値を指定して、関数を操作していけるようにしていこうと思います。
　　URLディスパッチとは何ぞやについては、こちらをご覧ください。
https://docs.djangoproject.com/ja/4.1/topics/http/urls/
URLで指定できる値の属性は、↓です。
詳細は上記リンクのPath convertersをご参照ください
![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3571777/6ebaa02a-8e31-7d41-bba9-6ebf61705c7b.jpeg)
今回は、URLで西暦年を指定したいのでint(数値型）を使用します。
（１）アプリケーションフォルダのurls.pyを作成する。
　　　前回作成したnorizo_appのurls.pyをコピペして修正します。
今回作成する関数をpathにつなげます（関数名はwareki)
「ｈｔｔｐ：／／ｗｗｗ．ｘｘｘｘ／ｎｏｒｉｚｏ＿ａｐｐ２／ｎｅｎ／９９９９」と指定するイメージです。
9999で指定される数字をseirekinenで受取り、view.pyの中で定義するwareki関数に
渡すイメージです。
![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3571777/77d931ea-1c6e-7fbf-bf9c-39264c1ab55f.jpeg)
（２）view.pyを作成します。
　　　前回作成したnorizo_appのview.pyをコピペして修正します。
      赤く囲ったところです。こんなかんじです。
　　　IF文のなかで、西暦年に応じた元号を設定し、西暦年を和暦年に変換します。
　　　和暦と元号をHttpResponseに返却します。
![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3571777/82859b68-72ba-e843-e87c-f5a80b174cd7.jpeg)
　（３）プロジェクトファイルのurls修正します。
       前回作成したnorizo_projectのurls.pyをコピぺしたうえで、
       赤く囲ったところを修正しました。
       プロジェクト名、アプリケーション名が変わっているので修正しています。
![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3571777/249937c7-3a99-e4f6-bc49-43e245bd44f5.jpeg)
（４）それでは起動してみます。
![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3571777/5d947894-d1b3-2e1b-4603-856b03930ea2.jpeg)
![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3571777/91712c34-223f-9d93-b4a7-d69be73efb34.jpeg)
この状態で、「127.0.0.1;8000/norizo_app2/nen/2023」と入力し
アプリケーションフォルダ(norizo_app2)にアクセスし、「nen」に紐づけられた
view.pyのwareki関数から結果が返却されるか確認します。
![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3571777/da3e84ce-b776-b6a5-2f74-0c904e765241.jpeg)
入力した西暦年2023と和暦が表示されます。
![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3571777/d83fc90e-4ddd-c11c-340f-db410e8c0040.jpeg)
![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3571777/592ce9d5-0330-7553-5a8b-38be54e23868.jpeg)
![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3571777/22b728da-e27e-55b0-41e7-1f659413969d.jpeg)
上手くいきました(^^♪
Javaで「文字列からの入力を行うスキャナを作成する」の動作を確認してみた

# 概要

Javaで「文字列からの入力を行うスキャナを作成する」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/start/scanner/index5.html

# 実装

以下のファイルを作成しました。
```JSample5_1.java
import java.util.Scanner;

class JSample5_1{
  public static void main(String[] args){
    Scanner scanner = new Scanner("120 78 92 46");

    while (scanner.hasNextInt()){
      int num = scanner.nextInt();
      System.out.println(num);
    }
  }
}
```

以下のコマンドを実行しました。
```
$ javac JSample5_1.java 
$ java JSample5_1 
120
78
92
46
```

# まとめ

何かの役に立てばと。
General error: 1364 Field 'uuid' doesn't have a default valueエラーが出た時の対処法

# エラーメッセージ


```
General error: 1364 Field 'uuid' doesn't have a default value (SQL: insert into `failed_jobs` (`connection`, `queue`, `payload`, `exception`, `failed_at`) values (database, default, {"uuid":"6c370f45-895f-4b6b-99dd-53443ddcfc61",...
```

# 原因
Laravelでジョブ失敗テーブルを作成し、わざと例外を発生させジョブを失敗させたところ該当のエラーが出現した。

原因としては`config/queue.php`の`'failed'`、`driver`に`database-uuids`設定されていなかったため。
日本語公式にも説明がなかったため注意が必要。

```.php
    /*
    |--------------------------------------------------------------------------
    | Failed Queue Jobs
    |--------------------------------------------------------------------------
    |
    | These options configure the behavior of failed queue job logging so you
    | can control which database and table are used to store the jobs that
    | have failed. You may change them to any database / table you wish.
    |
    */

    'failed' => [
        'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'), //これ
        'database' => env('DB_CONNECTION', 'mysql'),
        'table' => 'failed_jobs',
    ],
```

# 参考
https://readouble.com/laravel/10.x/ja/queues.html
Spoken English classes in Pune from SevenMentor

Here are some tips to help individuals learn to speak English faster, with a focus on using Spoken English classes in Pune from SevenMentor as a valuable resource:

Enroll in Spoken English Classes: Begin your journey by enrolling in Spoken English classes in Pune from SevenMentor. This provides a structured learning environment with experienced instructors.

Set Clear Goals: Define your language learning goals. Are you learning English for work, travel, or personal growth? Having clear objectives will keep you motivated.

Immerse Yourself: Surround yourself with English as much as possible. Watch English-language movies, listen to music, and read books in English. SevenMentor's classes can provide a supportive environment for this.

Practice Speaking Daily: Regular practice is key. Speak in English every day, even if it's just for a few minutes. SevenMentor's classes can offer speaking practice opportunities.

Expand Your Vocabulary: Learn new words daily. Use language learning apps or resources provided in your classes at SevenMentor to build your vocabulary.

Learn Grammar: Understanding English grammar rules is important for effective communication. Join SevenMentor's classes to grasp grammar concepts in-depth.

Converse with Native Speakers: If possible, engage in conversations with native English speakers. SevenMentor's classes may have native speakers or language exchange programs.

Record Yourself Speaking: Record your speech and listen to it. This helps in identifying areas for improvement and tracking your progress.

Join Online Language Communities: Participate in English language forums or social media groups to interact with fellow learners. Share experiences from your SevenMentor classes.

Read Aloud: Reading aloud improves pronunciation and fluency. Choose texts that are at your level and practice regularly.

Use Language Learning Apps: Download language learning apps like Duolingo, Rosetta Stone, or Babbel to supplement your classes.

Watch English News or TED Talks: These platforms offer a wealth of English content. SevenMentor may provide recommendations for such resources.

Stay Consistent: Consistency is key to mastering any language. Stick to your study schedule, and don't get discouraged by setbacks.

Get Feedback: Seek feedback from your instructors at SevenMentor and peers to pinpoint your strengths and weaknesses.

Travel and Practice: If possible, travel to English-speaking countries. Immersion accelerates the learning process.

Stay Patient and Positive: Learning a new language takes time. Stay positive and celebrate your achievements along the way.

By following these tips and leveraging the resources and expertise provided by <a href="https://www.sevenmentor.com/spoken-engilsh-classes-in-pune.php">Spoken English classes in Pune</a> from SevenMentor, you can accelerate your journey to becoming a confident English speaker.
Google DriveのファイルのURLを開くアカウントを指定する

ChatGPTに質問したら、3番目の方法を教えてくれたので、備忘録。

>google driveのファイルのURLをクリックしてブラウザで開く時に、どのアカウントから閲覧するかの情報を、URLに埋め込むにはどうすればよいですか

Google DriveのファイルのURLには直接アカウント情報を埋め込むことはできませんが、以下の方法で対処することが可能です。

1. **別のブラウザまたはプライベートウィンドウを使用する**: 別のブラウザやプライベートウィンドウ（インコグニートモードなど）を開いて、そこで必要なアカウントにログインしてからURLを開く方法です。

2. **アカウントを切り替える**: URLをクリックした後、右上のアカウントアイコンをクリックして切り替える方法があります。ただし、これはすでにページを開いてからの操作になります。

3. **URLを編集する**: これは非公式の方法ですが、Google DriveのURLの末尾に `?authuser=email@example.com` を追加することで特定のアカウントで開くように誘導することができる場合があります。ただし、これはGoogleによって公式にサポートされているわけではないので、将来的には動作しなくなる可能性があります。

例:
```
https://drive.google.com/file/d/FILE_ID/view?authuser=email@example.com
```

以上の方法で、特定のアカウントでGoogle Driveのファイルを開くことが可能です。
【初心者】FlutterでiOSアプリ画面を見ながら開発する方法

いざFlutterでiOSアプリを開発しようと重い腰を上げたら、環境構築からつまずいた、、

そんな人向けの備忘録的な記事です。

## 困ったこと

- ChromeやmacOSのUIなら起動できるが、iOSを見ながら開発が上手くできない
- `open -a Simulator` でできることもあれば、できないこともある。なぞだ

## 解決方法

1.  `open -a Simulator` でXcodeのSimulatorをまず開く
2. 上のメニューから「File > Open Simulator > iPhone 14 (好きなデバイス)」を選択
3. Simulatorを開いたまま、VSCodeで「mytest (createしたディレクトリ) > lib > main.dart」を開き、デバッグの拡張機能を開く
4. デバッグで「Flutter (iPhone 14) 」を選択

![Untitled (14).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/899381/a0207036-3d46-a914-8951-857f5469fba0.png)
![Untitled (16).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/899381/4398acbb-f34b-b2d8-2621-f8447d2e7698.png)


## 完了！

デフォルトでボタンを押した回数をカウントしてくれるアプリが作成されます！
スマホの見た目で画面操作できて良い。

![Untitled (17).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/899381/eca774a5-7652-eb38-785a-0f133fdce938.png)


※ 文章はもともと英語です、テキストだけ変えてみました

## 最後に

iOSアプリはあまりやってこなかったのですが、これを機にFlutter少し触ってみます。


## 参考

[FlutterアプリをGoogle Chrome/iOS Simulatorでデバッグする | DevelopersIO](https://dev.classmethod.jp/articles/try-debugging-the-flutter-app-with-google-chromeios-emulator/)
The command 'docker' could not be found in this WSL 2 distro.

# 事象 : Dockerがないといわれた
VisualStudioCodeからWSLにあるUbuntuでコンテナを起動しようとしたところ「Docker returned an error.」のメッセージが表示された。
ログを確認すると以下のメッセージが出力されていた。
```
The command 'docker' could not be found in this WSL 2 distro.
We recommend to activate the WSL integration in Docker Desktop settings.

For details about using Docker Desktop with WSL 2, visit:

https://docs.docker.com/go/wsl2/
```

## 原因 : Docker DesktopでUbuntuが有効になっていないから
- 環境
    - Windows 11 Pro バージョン22H2
    - Docker Desktop v4.24.1

Docker Desktopの設定をみると[General]にある「Use the WSL 2 based engine」はONになっているのになぜ？
WSLも2になっているし・・・と思って再度設定を確認する。
[Resoures] > [WSL integration]でなんと「Ubuntu」がOFFになっていた。

```bash
$ wsl -l -v
  NAME                   STATE           VERSION
* docker-desktop-data    Running         2
  docker-desktop         Running         2
  Ubuntu                 Running         2
```



### 対応 : Ubuntuを有効にする
設定の[Resoures] > [WSL integration] > [Enable integration with additional distros:]の「Ubuntu」をONにして[Apply & restart]する
「distro」は「ディストリビューション(distribution)」のこと、というのをちゃんと覚えて次はメッセージですぐに気が付けるようにしたい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1743295/a76a6862-14a9-8810-1593-bdbda61875fb.png)
Vuejs 検索フォームなど 日本語変換前の値を取得

普通はこっち。
```
<input type="search" v-model="word">
{{ word }}
```

これ(↓)だと日本語変換の確定前(ひらがなの状態など)でwordが変更される。リアルタイムの検索で便利。
```
<input type="search" :value="word" @input="word = $event.target.value">
{{ word }}
```
【Python】DBテーブルのレコードと類似したダミーレコードを大量に生成する方法

# 概要
ダミーDBを作成する際、とあるDBテーブルのレコードと類似したレコードを大量に入れたい、という状況になりました。
そこで、Pythonで大量にダミーデータを作成するコードを作成。

# サンプルコード
以下、サンプルコードです。
100-500文字ランダムに日本語が入るカラム`comment`があるので、`generate_random_text`という関数を定義しています。また、`sample_code`は`1`から`5`の数値が入るカラム、`id`は一意のものとします。

結果は、CSVファイルで出力されます。DBeaverとかだと、インポート機能がGUIで使えるのでダミーDBがすぐ出来上がります。

```py
import os
import pandas as pd
import random
from datetime import datetime


def generate_random_text(min_length, max_length):
    # ランダムな長さのテキストを生成
    length = random.randint(min_length, max_length)
    text = ''.join(random.choice('あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん、。！？') for _ in range(length))
    return text

# 元のデータ
original_data = {
    "id": 0,
    "request_no": "test_12345678",
    "sample_code": 3,
    "comment": "テストテストテストテストテストテストテストテストテストテストテストテストテストテスト",
    "create_date": "2023-10-05 09:18:17",
    "update_date": "2023-10-05 09:18:17",
}

# 1,000,000件の似たレコードを生成
num_records = 1000000
generated_records = []

for i in range(num_records):
    new_record = original_data.copy()
    new_record["id"] = original_data["id"] + i + 1
    new_record["request_no"] = f"test_{random.randint(10000000, 99999999)}"
    new_record["sample_code"] = random.randint(1, 5)
    new_record["comment"] = generate_random_text(100, 500) 
    current_datetime = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    new_record["create_date"] = current_datetime
    new_record["update_date"] = current_datetime
    
    generated_records.append(new_record)

# DataFrameに変換
df = pd.DataFrame(generated_records)

# 結果をCSVファイルに書き込む
output_file_name = "dummy_data.csv"
output_file_path = os.path.join('dummy_data', output_file_name)
df.to_csv(output_file_path, index=False)

print(f"{output_file_name} の作成が完了しました。")
```

似たようなファイルが大量にある場合は、同じディレクトリ(`dummy_generation_tool`)に全ておいた上で、以下のコマンドを実行すると一括生成してくれて便利です。上述の`Print`で進捗結果も出力されます。

```
find dummy_generation_tool -type f -name "*.py" -exec python {} \;
```

## その他：アレンジ
例えば、`request_no`を、ランダムではなく1から順番に採番したいときは、以下のようにすればOKです。
`08d`とすることで8桁の幅で表示するようゼロパディングできます。

```py
new_record["request_no"] = f"test_{i+1:08d}"
```

また、以下のように上限を決めてMAXまでいったら1に折り返す、としたい場合は`max_value`で以下のように指定してあげれば、`50000`まで採番され、その後折り返しが始まります。

```py
num_records = 1000000
generated_records = []
max_value = 50000

for i in range(num_records):
    value = (i % max_value) + 1
    new_record = original_data.copy()    
    new_record["request_no"] = f"test_{value:08d}"
```

`value = (i % max_value) + 1`は、ループ変数`i`を`max_value`で割った余りに1を加えて、`value`を計算します。これにより、`value`は`1`から`max_value`（ここでは`50000`）までの範囲で循環的に変化します。
Leetcode 1095. Find in Mountain Array

https://leetcode.com/problems/find-in-mountain-array/description/

# アプローチ
## Binary Search

# 説明
- Mountain Arrayなので、`配列のどこかの時点`で`一番大きい値が存在し、`その後`値が下げる`
- 一番大きい時点を確認する
- 大きい値までの左側を確認する
- 大きい値から右側を確認する

# コード
```java
/**
 * // This is MountainArray's API interface.
 * // You should not implement it, or speculate about its implementation
 * interface MountainArray {
 *     public int get(int index) {}
 *     public int length() {}
 * }
 */
 
class Solution {
    public int findInMountainArray(int target, MountainArray mountainArr) {
        // find top index
        int topIndex = 0;
        int left = 0;
        int right = mountainArr.length() - 1;
        while (left < right) {
            int mid = (left + right) / 2;
            if (mountainArr.get(mid) < mountainArr.get(mid + 1)) {
                left = mid + 1;
                topIndex = mid + 1;
            } else {
                right = mid;
            }
        }

        // check left of top index
        left = 0;
        right = topIndex;

        while (left <= right) {
            int mid = (left + right) / 2;
            int value = mountainArr.get(mid);
            if (value < target){
                left = mid + 1;
            } else if (value > target) {
                right = mid - 1;
            } else {
                return mid;
            }

        }

        // check right of  top index
        left = topIndex;
        right = mountainArr.length() - 1;

        while (left <= right) {
            int mid = (left + right) / 2;
            int value = mountainArr.get(mid);
            if (value > target) {
                left = mid + 1;
            } else if (value < target) {
                right = mid - 1;
            } else {
                return mid;
            }

        }

        return -1;
    }
}
```


## 参考にした解説

https://leetcode.com/problems/find-in-mountain-array/solutions/317607/java-c-python-triple-binary-search/
ts?tsx?ファイル名に迷うことありませんか

# はじめに

チームで開発を進めている時、
ファイルを新規追加するにあたり、
__.ts__ なのか __.tsx__ なのか迷う時がありました。

「とりあえず動いているからいっか」ぐらいの認識でいましたが、

__”イヤイヤ、今回はtsです”__
__”これはtsxなので、修正してもらっていいですか”__

と言われることがあまりに多いので、
流石に調べてみることにしました。

# 適当でも動くには動く

なんやかんやで、大抵、なんとかなっちゃうみたいです。
しかし主に２つの目的でファイル名を変えるらしいです。






### <font color="Red">1.JSX をサポートしているかどうか</font>
### .tsファイル
　__・純粋なTypeScriptファイル__
　__・JSX要素の追加はサポートしない__

### .tsxファイル
　 __・JSXも使えちゃうファイル__

<font color="Gray">　🔳JSXってなんやねん？
　マークアップとロジックを一緒のファイルに書けちゃう便利なやつ。
　下記のように、関数の中のリターンで"h1"タグとか入れたりできるらしいです
　JSXとReactはセットと思っていて間違いないみたい</font>

　![スクリーンショット 2023-10-12 17.28.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574859/56e77391-6bbb-c86c-4078-b4fb9f7320e2.png)

参考にJSXのドキュメントも貼っときますね
https://ja.legacy.reactjs.org/docs/introducing-jsx.html



### <font color="Red">2. どんなことを書くためのファイルなのかを明示するため</font>
一人で開発をやる人もいるかとも思いますが、
規模が大きくなるにつれて複数人で開発を行うことが主になるかと思います。
そんな時、ファイル名を変えておくことで仲間が理解しやすくなり、高速開発につながるようです。
（高速は言い過ぎかもですが、チリつもで結果的に意味のあるルールってやつみたいです)

特に人に見えるUIに関するコードを書くときは __.tsx__ にするらしいです。Reactを使って書くファイルですね！


# ひとりごと
やっぱり何かしらの意味があった。時間があるときもう少し詳しく勉強しよ・・・
気になったら調べるを癖づけなきゃ・・・
[UEFN] UEFNプロジェクトのサムネイル画像設定方法

# ゴール

UEFNのプロジェクト選択時に、サムネイル画像を設定する方法を共有します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/88a9719f-a2b4-342e-c3f0-404cd9442760.png)

# やり方

- 画像を準備する
    - png
    - 256×256
- 画像を配置する
- uefnprojectを編集する



# 画像を準備する

Feature Examplesのプロジェクトの「VerseStronghold」を今回参考にします。

- png (jpgでも可能かもしれないが)
- 256×256 (正方形であればもっと解像度高くても大丈夫ではありそう)

で画像を準備します。

![Icon256.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/79858f5f-1b39-c7ac-2721-547a3c8a6894.png)

# 画像を配置する

UEFNのディレクトリ構造はこうなっています。

- Fortnite Projects
    - {Project Name}
        - Plugins
            - {Project Name}
                - Content
                - {Project Name}.uplugin
        - .urcignore
        - {Project Name}.uefnproject

画像を置くのは、Plugins直下の{Project Name}ディレクトリ直下です。image.pngデータを置くとします。

- Fortnite Projects
    - {Project Name}
        - Plugins
            - {Project Name}
                - Content
                - **image.png** ←ここに置く
                - {Project Name}.uplugin
        - .urcignore
        - {Project Name}.uefnproject

# uefnprojectを編集する

{Project Name}.uefnprojectを任意のテキストエディタで開きます。

VerseStrongholdのサンプルの場合こうなっています。

```json:{Project Name}.uefnproject
{
	"fileVersion": 14,
	"versionSuffix": "",
	"title": "VerseStronghold",
	"description": "An AI example to showcase a game mode in which the goal is for players to eliminate all hostile enemies at a heavily guarded Stronghold.",
	"keyArt": "",
	"docsUrl": "",
	"attributions": [],
	"kind": "Island",
	"templateCategory": "UserGenerated",
	"compatibilityVersion": "26.00",
	"editorPermissions": [],
	"epicApp": "",
	"sortPriority": 0,
	"plugins": [
		{
			"name": "VerseStronghold",
			"bIsRoot": true,
			"bIsPublic": false,
			"bEnabled": true
		}
	],
	"dataSets":
	{
		"matchmaking":
		{
			"maxPlayers": 4,
			"maxTeamCount": 1,
			"maxTeamSize": 4,
			"maxSocialPartySize": 4,
			"allowJoinInProgress": false,
			"allowSquadFillOption": true,
			"version": 1
		}
	},
	"bindings":
	{
		"projectId": "1a6e830d-449b-448c-982c-479133099dea",
		"modules":
		{
			"VerseStronghold": "6771178c-4048-b922-0498-888403de0fca"
		}
	}
}
```

この"keyArt"の値をpngのファイル名にしてください。今回であれば `image.png`です。

```json:{Project Name}.uefnproject
	"keyArt": "image.png",
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/fd560c48-ff33-e67f-62d7-8b16fe41b168.png)

保存したあとに、UEFNを再起動するとサムネイルが登場します。

## 応用:画像を置くディレクトリを作る

画像を置くのはPlugins直下の{Project Name}ディレクトリからの相対パスなので、直下ではなく、フォルダを挟んで配置することもできます。

例えば、VerseStrongholdのサンプルの元々は以下のようなディレクトリ構成です。

- Fortnite Projects
    - {Project Name}
        - Plugins
            - {Project Name}
                - Content
                - Resources //ファルダを1つ挟む
                    - *Icon256.png** // ←ここに置く
                - {Project Name}.uplugin
        - .urcignore
        - {Project Name}.uefnproject

その上で、uefnprojectファイルは

```json:{Project Name}.uefnproject
	"keyArt": "Resources/Icon256.png",
```

と設定されています。
このような設定も可能だと頭に入れておくと良いかもしれません。

# 参考資料

https://www.youtube.com/watch?v=ho0UzLih0Yo
GAS備忘録(Google Apps Script)

# Abstract
GAS備忘録. 主にGoogleSpreadSheetについて。
# 内容
基本
- その0. スタンドアロン型 or コンテナバインド型を選ぶ
    - スタンドアロン型
        - Googleサービス全般と連携した独立のスクリプトを作りたい場合
        - 複数のスプレッドシートを活用したい場合もこれ
        - Googleドライブから新規作成
    - コンテナバインド型
        - スプレッドシート操作中にちょっとした自動化したいだけの場合
        - Google Sheetsのスクリプトエディタから作成
- その1.基本の4オブジェクト
    - SpreadsheetAppオブジェクト
        - スプレッドシートアプリの最上位オブジェクト
    - SpreadSheetオブジェクト
        - 1個のファイル全体
    - Sheetオブジェクト
        - 左下の「シート1」「シート2」みたいな一個一個のシート
    - Rangeオブジェクト
        - セルの範囲
- その2.スプレッドシートの取得法の3種類
    - アクティブなスプレッドシートを取得
    - URLを指定して取得
    - IDを指定して取得
- その3. シートの取得方法
    - 参考:
        - https://tonari-it.com/gas-spreadsheet-get-sheet/#toc5
    - コンテナバインドかつシートの数が一つだけの場合
        - getActiveSheet
    - それ以外
        - getSheetByName
```
// コンテナバインドスクリプトであれば、これで取得できる
var spreadsheet_1 = SpreadsheetApp.getActiveSpreadsheet();

// URLを使って取得できる
var url = 'https://docs.google.com/spreadsheets/d/xxxxxx/edit#gid=0';
var spreadsheet_2 = SpreadsheetApp.openByUrl(url);

// IDを使って取得できる
var id = 'xxxxxx';
var spreadsheet_3 = SpreadsheetApp.openByID(id);

```
- その3. メソッド
    - 値取得

```
function myFunction() {
    var sheet = SpreadsheetApp.getActiveSheet();

    // セルのデータを取得するときは getValue() を用いる
    Logger.log(sheet.getRange('A2').getValue()); // Tom


    // 指定した範囲のデータを取得するときは getValues() を使用する
    Logger.log(sheet.getRange('A3:C4').getValues()); // [[John, male, 28.0], [Emma, female, 31.0]]
}

```
    - 値入力
```
function myFunction() {
    var sheet = SpreadsheetApp.getActiveSheet();

    // セルにデータを入力するときは setValue() を用いる
    sheet.getRange('A5').setValue('Anthony');
    Logger.log(sheet.getRange('A5').getValue()); // Anthony

    // 指定した範囲にデータを入力するときは setValues() を使用する
    sheet.getRange('B5:C5').setValues([['male', 34]]);
    Logger.log(sheet.getRange('A5:C5').getValues()); // [[Anthony, male, 34.0]]
}

```
    - 行の追加

```
function myFunction() {
    var sheet = SpreadsheetApp.getActiveSheet();

    // データを追加する
    sheet.appendRow(['Luna', 'female', 30]);

    // 式も代入できる
    sheet.appendRow([null, null, '=AVERAGE(C2:C6)']);
}

```


# 参考文献
https://note.com/skipla/n/n0803937a0887
https://michikusa.biz/introduction-to-gas-2/
https://qiita.com/zumi0/items/82ebe9797811c8d670ac#%E3%82%B9%E3%83%97%E3%83%AC%E3%83%83%E3%83%89%E3%82%B7%E3%83%BC%E3%83%88
https://qiita.com/km42428/items/845975277e635e70adfc
salesforce custom tab tabstyle 日英対照

    番号(ID)	日本語	英語
    Custom1     ハート	Heart
    Custom10	月	    Moon
    Custom100	ワイドテレビ	TVWidescreen
    Custom11	星	Star
    Custom12	円	Circle
    Custom13	箱	Box
    Custom14	手	Hands
    Custom15	人	People
    Custom16	銀行	Bank
    Custom17	袋	Sack
    Custom18	プリント	Form
    Custom19	レンチ	Wrench
    Custom2	    扇風機	Fan
    Custom20	飛行機	Airplane
    Custom21	コンピューター	Computer
    Custom22	電話機	Telephone
    Custom23	封筒	Envelope
    Custom24	ビル	Building
    Custom25	目覚まし時計	Alarmclock
    Custom26	旗	Flag
    Custom27	ラップトップ	Laptop
    Custom28	携帯電話	Cellphone
    Custom29	PDA	PDA
    Custom3	    太陽	Sun
    Custom30	パラボラアンテナ	Radardish
    Custom31	自動車	Car
    Custom32	工場	Factory
    Custom33	机	Desk
    Custom34	昆虫	Insect
    Custom35	マイクロフォン	Microphone
    Custom36	機関車	Train
    Custom37	橋	Bridge
    Custom38	カメラ	Camera
    Custom39	望遠鏡	Telescope
    Custom4	    六角形	Hexagon
    Custom40	クレジットカード	Creditcard
    Custom41	現金	Cash
    Custom42	宝箱	Treasurechest
    Custom43	宝石	Jewel
    Custom44	ハンマー	Hammer
    Custom45	チケット	Ticket
    Custom46	切手	Stamp
    Custom47	騎士	Knight
    Custom48	トロフィー	Trophy
    Custom49	CD/DVD	CD/DVD
    Custom5	    葉	Leaf
    Custom50	サーカス	Bigtop
    Custom51	りんご	Apple
    Custom52	ボール	Balls
    Custom53	ベル	Bell
    Custom54	ボート	Boat
    Custom55	本	Books
    Custom56	瓶	Bottle
    Custom57	ビルディングブロック	BuildingBlock
    Custom58	使者の杖	Caduceus
    Custom59	缶	Can
    Custom6	    三角形	Triangle
    Custom60	傘	Umbrella
    Custom61	城	Castle
    Custom62	黒板	Chalkboard
    Custom63	チップ	Chip
    Custom64	コンパス	Compass
    Custom65	カップ	Cup
    Custom66	サイコロ	Dice
    Custom67	歯車	Gears
    Custom68	地球	Globe
    Custom69	ギター	Guitar
    Custom7	    正方形	Square
    Custom70	のこぎり	Handsaw
    Custom71	ヘッドセット	Headset
    Custom72	ヘリコプター	Helicopter
    Custom73	高速道路標識	HighwaySign
    Custom74	気球	HotAirBalloon
    Custom75	IP 電話	IPPhone
    Custom76	鍵	Keys
    Custom77	ロック	Locked
    Custom78	地図	Map
    Custom79	巻尺	MeasuringTape
    Custom8	    ダイアモンド	Diamond
    Custom80	オートバイ	Motorcycle
    Custom81	音符	MusicalNote
    Custom82	笛	Whistle
    Custom83	鉛筆	Pencil
    Custom84	プレゼンター	Presenter
    Custom85	看板	RealEstateSign
    Custom86	赤十字	RedCross
    Custom87	金庫	Safe
    Custom88	ヨット	Sailboat
    Custom89	サックス	Saxophone
    Custom9	    稲妻	Lightning
    Custom90	天秤	Scales
    Custom91	盾	Shield
    Custom92	船	Ship
    Custom93	ショッピングカート	ShoppingCart
    Custom94	聴診器	Stethoscope
    Custom95	ストップウォッチ	Stopwatch
    Custom96	道路標識	StreetSign
    Custom97	温度計	Thermometer
    Custom98	トラック	Truck
    Custom99	ブラウン管テレビ	TVCRT
ServerのSSLが反映されるまでの時間【https】

5分くらいで反映されます。

```bash
while true; do date; curl -s https://example.com/ | grep title; sleep 10; done
Thu Oct 12 09:11:23 JST 2023
Thu Oct 12 09:11:33 JST 2023
Thu Oct 12 09:11:43 JST 2023
Thu Oct 12 09:11:53 JST 2023
Thu Oct 12 09:12:03 JST 2023
Thu Oct 12 09:12:13 JST 2023
Thu Oct 12 09:12:24 JST 2023
Thu Oct 12 09:12:34 JST 2023
Thu Oct 12 09:12:44 JST 2023
Thu Oct 12 09:12:54 JST 2023
Thu Oct 12 09:13:04 JST 2023
Thu Oct 12 09:13:15 JST 2023
Thu Oct 12 09:13:25 JST 2023
Thu Oct 12 09:13:35 JST 2023
Thu Oct 12 09:13:45 JST 2023
Thu Oct 12 09:13:55 JST 2023
Thu Oct 12 09:14:06 JST 2023
Thu Oct 12 09:14:16 JST 2023
Thu Oct 12 09:14:26 JST 2023
Thu Oct 12 09:14:36 JST 2023
Thu Oct 12 09:14:46 JST 2023
Thu Oct 12 09:14:57 JST 2023
Thu Oct 12 09:15:07 JST 2023
Thu Oct 12 09:15:17 JST 2023
<title>無効なURLです</title>
Thu Oct 12 09:15:27 JST 2023
<title>無効なURLです</title>
Thu Oct 12 09:15:37 JST 2023
<title>無効なURLです</title>
Thu Oct 12 09:15:48 JST 2023
<title>無効なURLです</title>
Thu Oct 12 09:15:58 JST 2023
<title>無効なURLです</title>
```
無効なURLです。プログラム設定の反映待ちである可能性があります。しばらく時間をおいて再度アクセスをお試しください。

**無効なURLです。\nプログラム設定の反映待ちである可能性があります。\nしばらく時間をおいて再度アクセスをお試しください。** と表示された場合、５５分経つと解除されます。

私の環境では9時5分にインストールし、10時00分に「無効なURLです。」が解除されました。

```html:index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta name="robots" content="noindex,nofollow">
<title>無効なURLです</title>
</head>

<body>

<p>
無効なURLです。<br />
プログラム設定の反映待ちである可能性があります。<br />
しばらく時間をおいて再度アクセスをお試しください。
</p>

</body>
</html>
```
Snowflake の外部ステージからの COPY INTO が遅かった話

Snowflake の COPY INTO クエリが遅かったが、書き方を変えたら速くなった話。

## 背景
Amazon S3 に以下のような構造でデータがあり、これを Snowflake に取り込みたい。

```
s3://my-bucket/
  ├ foo/
  │   ├ aaa.csv.gz
  │   ├   :
  │   └ zzz.csv.gz
  ├ bar/
  │   ├ aaa.csv.gz
  │   ├   :
  │   └ zzz.csv.gz
  :
  (略)
```

`foo/` `bar/` などの各ブロックごとに数十万ファイルあり、S3 バケット全体では数百万ファイルある。

## 課題
Snowflake の INTEGRATION や STAGE などの設定は済ませた上で、下記のようなクエリを実行すればテーブル foo にデータを取り込むことができる。

``` sql
COPY INTO foo FROM @my_stage pattern='foo/.+[.]csv[.]gz';
```

が、クエリ実行がなんだか遅い。

様子を見ていると「Listing external files...」だけで20分以上かかっている。
ファイル一覧を列挙するだけなのにそんなに時間かかる？

## 原因
`pattern='foo/.+[.]csv[.]gz'` と書けばよしなに `foo/` 以下だけを見てくれるものと思い込んでいたのだけど、どうやらそんなことはなくて、`@my_stage` 全体のファイル一覧を取得した上で pattern でフィルタリングをしている模様...。そりゃあ遅い。

[COPY INTO <テーブル> | Snowflake Documentation](https://docs.snowflake.com/ja/sql-reference/sql/copy-into-table)

> 最高のパフォーマンスを得るには、多数のファイルをフィルターするパターンを適用しないようにしてください。

> 一括データロード操作は、 FROM 句の保存場所全体に正規表現を適用します。

ドキュメントにも書かれていた。

## 解決策
`FROM` 句にパスを指定して絞り込むようにしたところ、爆速になった。

``` sql
COPY INTO foo FROM @my_stage/foo/ pattern='.+/.+[.]csv[.]gz';
```

## (おまけ) 計測結果
ファイル一覧を取得する時間だけを計測してみると、これくらい爆速になった。

``` sql
LIST @my_stage pattern='foo/.+[.]csv[.]gz';
```

→ 24分

``` sql
LIST @my_stage/foo/ pattern='.+/.+[.]csv[.]gz';
```

→ **2秒**