OmniAICreator/Qiita-1.07M huggingface dataset:
Data Distribution Service(DDS)について

# 背景
DDSについて調べたことをまとめておく。

リアルタイムおよび分散型システム間でデータを交換するための標準化された通信プロトコル。
DDSは、IoT（Internet of Things）や組み込みシステム、産業用自動化など、さまざまな領域で広く使用されている。
DDSは、リアルタイム性、信頼性、スケーラビリティに焦点を当てており、複数のデバイスやシステム間でデータを共有するための効率的で柔軟な手段を提供する。

https://www.omg.org/omg-dds-portal/

# 通信仕様（概略）

https://www.dds-foundation.org/what-is-dds-3/

Data Distribution Serviceというくらいなので、データ中心の通信サービスである。
Dataを更新するアプリケーションを「Publisher」、
Dataを参照するアプリケーションを「Subscriber」と呼び、
それぞれが、Topicと呼ばれるデータにアクセスする。
「Publisher」と「Subscriber」はお互いがどんなシステム上にあるのかを意識する必要がなく、
DDSのミドルウェアが高速に処理してくれる。


![スクリーンショット 2024-05-12 13.46.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/4ac9e827-5985-5a8d-7711-89a2d93439c5.png)

以下の図のようにグローバルなデータベースに各システムがアクセスするイメージだが、
実際はそんなデータベースなど存在せず、DDSの通信プロトコルに従いP2Pで通信する。

![スクリーンショット 2024-05-12 13.51.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/2af26274-6b2f-7899-bca0-262660159082.png)

※やりたいことはSOME/IPとほぼ同じだと感じた。

# セキュリティ
https://www.omg.org/spec/DDS-SECURITY/1.1/PDF

# SOME/IPとの違い

以下はChatgptにDDSとSOME/IPとの違いを聞いてみた。


>データ配信モデル:
DDS: DDSはパブリッシュ/サブスクライブモデルを使用しており、データの生産者（パブリッシャー）と消費者（サブスクライバー）が明確に分離されています。データが配信されると、サブスクライバーはそれを受信します。
SOME/IP: SOME/IPはクライアント/サーバーモデルを使用しており、クライアントがサーバーにリクエストを送信し、サーバーがそれに応答します。このモデルは、リクエスト/レスポンス型の通信に適しています。
メッセージ形式:
DDS: DDSは柔軟なデータ型をサポートし、構造化されたデータや非構造化データなど、さまざまな形式のメッセージを配信できます。
SOME/IP: SOME/IPは主にメソッド呼び出しや通知の形式を使用し、RPC（Remote Procedure Call）のようなメッセージングパターンに焦点を当てています。
リアルタイム性:
DDS: DDSはリアルタイム性が高く、データの配信や受信が遅延せず、予測可能な時間内で行われます。
SOME/IP: SOME/IPもリアルタイム性を重視していますが、DDSほど広範なリアルタイムアプリケーションには使用されません。
適用領域:
DDS: DDSは広範な領域で使用されており、IoT、自動車業界、航空宇宙などの分野で利用されています。
SOME/IP: SOME/IPは主に自動車業界で使用されており、車載システムやエレクトロニクスアーキテクチャの間で通信を行うために採用されています。
総括すると、DDSとSOME/IPはどちらも分散型システム間で通信を行うためのプロトコルですが、通信モデルやメッセージ形式、適用領域などにおいて異なる特性を持っています。

また、以下で性能評価がされていた。

https://ipsj.ixsq.nii.ac.jp/ej/?action=repository_uri&item_id=186475&file_id=1&file_no=1

この研究報告では、簡単にいうと
・SOME/IPは、ROM/RAM使用量が小さいが、パケットロス率が高い。
・DDSは、ROM/RAM使用量が大きいが、メッセージサイズが大きくても効率良く、かつパケットロス率は少なく高信頼な通信が可能。

つまり、SOME/IPではCPUリソースの乏しくても適用可能、
DDSはパフォーマンスの高いマシンで適用すると効率が良い。
ただ、システム上にあるECUがすべて同じ通信プロトコルを採用しないと意味ないので、
システム上にCPUリソースの乏しいECUがあるとSOME/IPを採用することになる？

テキトーに調べてみた結果、DDSは以下のようなシステムに適用事例があるらしい。
やっぱり大量生産するような車載システムでは、
コストを抑えるために末端CPUはリソース制限が厳しいと思うので、DDSは採用しないのでは？と思った。
AUTOSAR仕様になっているので、本当に採用する製品があるのか気になる。

>Wikiより：
代表的なものとして、米海軍オープンアーキテクチャ(Naval Open Architecture: 略称OA)に採用され、その後OA毎米国防総省全体の調達規格(COTS)に組み込まれた。この影響で旧西側同盟諸国を始めとする各国で軍用・民生用を問わずに採用されている。(米海軍強襲揚陸艦 LPD-17を皮切りに米海軍個艦防衛システム"SSDS"、艦内ネットワーク"SWAN"、AEGISシステムを構成するレーダー・ソナー・FCS・各種兵装、"SWAN"を更新した"TSCEi"(Zumwalt DDG 1000等)、カナダ航空管制システム、欧州航空管制システム(西側でRTI Connext、東側でOpenSpliceが採用されている)、スゥエーデン SAAV 9LVなどに採用。

>他の例：
戦艦
ダムのような大規模施設
金融システム
宇宙、航空システム
電車の線路切り替え機
1915. Number of Wonderful Substrings の解き方メモ

https://leetcode.com/problems/number-of-wonderful-substrings/description

# 問題の概要

文字列wordの部分文字列のうち、理想文字列であるものを求める問題です。理想文字列とは、奇数個の文字が0個もしくは1個しかない文字列とします。

# 解き方メモ

累積和を格納した配列Pを定義します。

```
P[x] = ( word[0,x)のaの個数, word[0,x)のbの個数 ... word[0,x)のjの個数 )
```

累積和の性質を考えると、word[x, y)の文字の個数はP[y] - P[x]となります。

---

例として、P[y] = (偶数, 奇数, 偶数) となっているとしましょう。word[x,y)が奇数個の文字を含まない場合、P[y] - P[x] = (偶数, 偶数, 偶数)となります。

```
P[x] = P[y] - (P[y] - P[x])
     = (偶数, 奇数, 偶数) - (偶数, 偶数, 偶数)
     = (偶数, 奇数, 偶数)
```

つまりP[x] = (偶数, 奇数, 偶数)となるxの数をカウントすれば、奇数個の文字を含まない理想文字列をカウントすることができるわけです。

同じように、word[x,y)がaのみ奇数個の理想文字列とすると、P[y] - P[x] = (奇数, 偶数, 偶数)であり、上記と同じように式を展開すると、P[x] = (奇数, 奇数, 偶数)とわかります。

bのみ奇数個の理想文字列、cのみ奇数個の理想文字列 ... jのみ奇数個の理想文字列についてもまったく同じことがいえます。

---

yを0からnの範囲で動かしつつ、以下の条件を満たすようなxの数をPの性質を利用して、それぞれカウント。その合計がもとめる理想文字列の総数となります。

- word[x,y)が奇数個の文字を含まない理想文字列になるようなx
- word[x,y)がaのみ奇数個の理想文字列になるようなx
- ... 
- word[x, y)がjのみ奇数個の理想文字列になるようなx

```rust
use std::collections::HashMap;

impl Solution {
    pub fn wonderful_substrings(word: String) -> i64 {
        let word = word.chars().collect::<Vec<_>>();
        let n = word.len();

        let mut P = vec![vec![0_i32; 10]; n+1];
        for i in 0..n {
            for ch in 'a'..='j' {
                if ch == word[i] {
                    P[i+1][ch as usize - 'a' as usize] = P[i][ch as usize - 'a' as usize] + 1;
                } else {
                    P[i+1][ch as usize - 'a' as usize] = P[i][ch as usize - 'a' as usize];
                }
            }
        }

        let mut counter = HashMap::new();
        let mut ret = 0;
        for y in 0..=n {
            let y_key = (0..10).map(|i| P[y][i] % 2).collect::<Vec<_>>();
            
            // 奇数個の文字がない場合
            let yx_key = vec![0; 10];
            let x_key = (0..10).map(|i| (yx_key[i] - y_key[i]).abs()).collect::<Vec<_>>();
            ret += counter.get(&Self::to_tuple(&x_key)).unwrap_or(&0);

            // aだけが奇数個の場合、bだけが奇数個の場合…
            for i in 0..10 {
                let mut yx_key = vec![0; 10];
                yx_key[i] = 1;

                let x_key = (0..10).map(|i| (yx_key[i] - y_key[i]).abs()).collect::<Vec<_>>();
                ret += counter.get(&Self::to_tuple(&x_key)).unwrap_or(&0);
            }

            *counter.entry(Self::to_tuple(&y_key)).or_insert(0) += 1;
        }
        
        ret
    }

    fn to_tuple(v: &Vec<i32>) -> (i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
        return (v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9]);
    }
}
```
ITパスポート&基本情報技術者試験を受けてみた

# はじめに
ITパスポート&基本情報技術者試験を受けた時の勉強方法などを書いていきます。
これから受けようと考えている方の参考になれば幸いです。

# なぜ受けようと思ったか
受託開発で請け負っていたプロジェクトが終わり、次のプロジェクトに入るまでに数週間空いていたため、その間に何か勉強しようと思っていました。

自分は未経験からWeb業界へ入った身であり、情報系の学部出身でもないので、プログラムはある程度書けるものの基礎知識が足りていない実感がありました。
そこで、情報系の資格の一つである基本情報技術者試験を勉強し受けてみようと思いました。

あまり資格を取っておらず受験勉強ともご無沙汰だったので、まずは勉強と受験の感覚を掴むためにITパスポートを先に受けようと思いました。

# 勉強時間
受験までの勉強時間は以下の通りでした。（参考：実務経験1年3ヶ月）
ITパスポート：約20時間
基本情報：約50時間

# 勉強方法
### 1. 過去問道場でひたすら過去問を解く
[ITパスポート過去問道場](https://www.itpassportsiken.com/ipkakomon.php)
[基本情報技術者過去問道場](https://www.fe-siken.com/fekakomon.php)

無料のアカウント登録をするだけで、今まで解いた問題の正答率を出してくれたり、間違えた問題だけを復習するコースを受けたりすることができます。
「模擬試験形式で出題」にすると試験の分野毎に問題数を合わせて出題してくれるのでおすすめです。

### 2. 参考書を読む
[キタミ式イラストIT塾 基本情報技術者](https://gihyo.jp/book/2023/978-4-297-13807-3)

過去問道場の過去問を解いて分からなかった箇所は都度、キタミ式の索引で調べて解説を読むようにしました。
ITパスポートも基本情報と出題範囲が似ているので、始めから基本情報用の参考書を使っても問題なかったです。

中古で買った令和2年版を途中まで使っていましたが、本屋で令和6年版を見かけたので読んでみると「索引の用語数が多くなっている！」と思い、急遽令和6年版を購入しました。
令和2年版にはなかった解説も追加されていたので、最新版を購入して使う方が良いかもしれません。

### 3. 過去問道場の復習モードを実施する
一度分からなかった問題が分かるようになるまで復習モードで解いていきました。
また分からなくなったらキタミ式で調べて解説を読んでいきます。

通常の復習モードだけでなく、チェックを付けた問題だけを復習できる機能もあるので、正解したけど自信がなかった問題にはチェックを付けておき、あとで復習するようにしました。

ITパスポート、基本情報は共に合格点が60%以上のため、正答率が70〜80%くらいになるように勉強を進めました。
苦手な分野は「分野を指定して出題」で分野を選択し、集中的に解くようにしました。

### 基本情報の科目Bについて
科目Bは令和5年度から開始されたため、過去問が1年分しかありませんでした。

しかし過去問を解いてみると、擬似言語は実務のプログラミングと似ており、プログラミング経験があれば解けそうな感触でした。
セキュリティ問題は科目Aの勉強をしていれば問題なく解けそうです。

出題形式に慣れておくため、令和5年度の過去問とサンプル問題はひと通り解きました。
念のため科目B対策用の参考書も購入しましたが、一度も使いませんでした。。

# 試験について
試験はCBT方式で電卓持ち込み不可です。そのため、勉強時から過去問道場の電卓機能を使わずに紙とペンを使って計算するようにしました。
また、過去問道場では不要な選択肢に削除線を引ける便利な機能があるのですが、実際の試験にはそのような機能はないので、あまり使わない方がいいかもしれません。。

試験後はすぐに得点が出ました。合格点を超えていて一安心です。
ITパスポート：67%
基本情報 科目A：70%
基本情報 科目B：82%

# 受けてみての所感
ITパスポートは基本的な用語や一般常識を問うが多かったので、IT実務経験がある人はそこまで勉強しなくても合格できるかもしれません。
基本情報はITパスポートよりも一歩踏み込んだ知識や計算問題が出題されるため、やっぱり少し勉強が必要だなと感じました。（特にn進数、コンピュータ周りの知識）
また、どちらの試験でも過去問とほぼ同じ問題も出題されたので、過去問を中心に勉強していて良かったなと思いました。

次は応用情報技術者試験に向けて勉強しようかなと思います。
生成AIを使ったサービスは何故流行らせるのが難しいのか？

下記動画の内容を記事として要約しました。

<iframe width="560" height="315" src="https://www.youtube.com/embed/jcUxm01dmbY?si=B_7DYkpeAiHd79sO" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>


## 生成AIサービス開発の現状
多くの企業がOpenAIのような大手からAPIを利用して、チャットボットやその他のAIサービスを開発しています。技術の進歩により、専門的な知識がなくても生成AIをサービスに組み込むことが可能になっています。

## 開発が難しい理由
### 競争と革新の速度
OpenAIのような企業が技術を牽引し続けているため、小さな企業や新規参入者が市場に影響を与えるのが難しいです。

### 特化したアプリケーションの不足
多くの場合、生成AIを活用する具体的な用途が限られており、それがサービスの普及を妨げています。

### 高コストと技術的ハードル
言語モデルの開発と運用には高額なコストと技術的な専門知識が必要で、これが障壁となっています。

## 生成AIの有用な活用方法
生成AIは、ユーザーの行動や好みを分析し、パーソナライズされた推薦やサポートを提供するために有効に利用できます。例えば、ECサイトでユーザーの購買履歴から次に興味を持ちそうな商品を推測し、推薦することが可能です。

## 未来の展望
生成AIの技術は引き続き進化し、新しいビジネスモデルやアプリケーションが開発されるでしょう。しかし、大手企業が支配的な役割を担い続けることで、新規参入者が市場に参入するのは依然として難しいかもしれません。生成AIの将来は明るいものの、その道のりは複雑で挑戦的です。











<iframe width="560" height="315" src="https://www.youtube.com/embed/jcUxm01dmbY?si=B_7DYkpeAiHd79sO" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
アジャイル開発の基本

# はじめに
Udemyのコース「現役アジャイルコーチが教える！半日で理解できるアジャイル開発とスクラム」で学んだことを備忘録として記録します。

# 用語
- ユーザーストーリー
やりたいこと。バックログアイテムとも呼ばれる。
- バックログ
やることリスト。
- ストーリーポイント
ユーザーストーリーを見積もる方法。

# アジャイル開発の手法

## スクラム
現在最も有名な開発手法。

### 特徴
- シンプルなフレームワークで人気
- ソフト開発以外でも使われている

### 理論
- 経験主義
透明性→検査→適応
スプリントごとにレビューを繰り返すのは検査
- リーン思考
無駄を減らすこと。
無駄なく3本柱を回していく。

## XP（エクストリームプログラミング）
### 特徴
1. コミュニケーション
1. シンプルさ
1. フィードバック
1. 勇気
1. 尊重

### プラクティス
1. 全員同席
1. チーム全体
職能横断型チームを作る
難しい場合は外部の協力を得る
1. 情報豊富な作業空間
1. 活気ある仕事
残業ベースで働かない
1. ペアプログラミング
知識や経験を倍速で積んでいく
1. ストーリー
ユーザーの要求を小さくまとめ管理する
1. 1週間サイクル
短い期間で開発とリリースを繰り返す
1. 四半期サイクル
中長期的な計画も出来るだけ作る
1. ゆとり
1. 10分ビルド
特定の短い時間内にビルドを終わらせる
1. 常時結合
継続的インテグレーション（CI）
1. テストファーストプログラミング
1. インクリメンタル設計
少しずつ設計しましょう

### 応用プラクティス
1. 実顧客の参加
ユーザーを巻き込む
1. インクリメンタル配置
継続的デリバリ（CD）
1. チームの継続
チームとして成熟度を高めていく
1. チームの縮小
意欲ある経験者で別チームを立ち上げる
1. 根本原因の分析
表面的な問題にとらわれずに問題を深堀する
1. コードの共有
1. コードとテスト
1. 単一のコードベース
1. 日次配置
1. 協議によるスコープ契約
1. 利用分払い

## リーンソフトウェア開発
### 原則
1. 無駄をなくす
1. 品質を作り込む
欠陥をあとで見つけようとしない
1. 知識を作り出す
1. 決定を遅らせる
1. 速く提供する
1. 人を尊重する
1. 全体を最適化する

## かんばん
### 基本原則
1. 現在、何をしているかを理解することから始める
ホワイトボードに書き出す。かんばんにする。
1. インクリメンタルに進化させ、変化を追求していく
1. 現状のプロセス、役割、責務、職位を尊重する
1. すべての地位でのリーダーシップを求める

### コアプラクティス
1. 可視化する
1. WIPを制限する
1. 流れを管理する
1. 明確なポリシーを作る
1. フィードバックループを実現する
1. コラボレーティブに改善し、実験的に進化する

## DevOps
開発と運用の効率的・効果的なコラボレーションをベースとしている

### ツール
- コード
GitHubなど
- ビルド
JenkinsなどのCIツール
- テスト
自動テスト
- パッケージ
コンテナ技術、ライブラリ管理
- リリース
リリース自動化
- コンフィグレーション
インフラ自動構築、オーケストレーションツール
- モニター
パフォーマンスモニタリングツール

### DevOpsの目標
- デプロイの頻度
- 変更のリードタイム
- 変更失敗率
- 平均修復時間


## スクラム
- スクラムガイドはわずか18ページ
- 時代に応じて更新されていく

### 概要
複雑な問題に対応する適応型のソリューションを通じて、人々・チーム・組織が価値を生み出すための軽量級フレームワーク

開発を行う際は、シンプルかどうかを重視

### 流れ
1. プロダクトバックログ
やることリスト
1. スプリントバックログ
短い期間のやることリスト
1. デイリースクラムミーティング

### スクラムチーム
- プロダクトオーナー
やることややる順番を決める。
最終的な決定責任がある。
- 開発者
開発を行う。
- スクラムマスター
スクラムの理論を全員に理解させる。

人数は10人以内が推奨。

#### プロダクトオーナー
##### 責任
1. ゴールを策定し、明示的に伝える
1. プロダクトバックログアイテムを作成し、明確に伝える
1. プロダクトバックログアイテムを並び替える
1. プロダクトバックログに透明性があり、見える化され、理解されるようにする

#### 開発者
##### 責任
- スプリントバックログを作成する
- 完成の定義を忠実に守ることにより、品質を作り込む
- スプリントゴールに向けて毎日計画を適応させる
- 専門家としてお互いに責任を持つ

#### スクラムマスター
- チームメンバーをコーチする
- チームが集中できるよう支援する
- 進捗を妨げる障害物を排除するように働きかける
- すべてのスクラムイベントが開催され、ポジティブで生産的であり、タイムボックスの制限が守られるようにする

#### スクラムイベント
##### スプリント
-　固定の期間を指す
-　2週間が一般的。まず1週間を試すのが良い。

##### スプリントプランニング
- スプリントの計画を立てる
- スプリントバックログを決めること
- スプリントゴールを決める
- POはスプリントバックログを選ぶ
- 見積（ストーリーポイント）、スコープを決める
- 必要な場合、スプリントバックログをタスクに分割する

##### デイリースクラム
- 朝礼、15分以内のイベント
- スプリントゴールの進捗を確認し、計画を再計画
- 問題や課題の対策も考え、意思決定する
- 3つの質問を行う
    - 昨日やったこと
    - 今日やること
    - 課題や不安

##### スプリントレビュー
- 成果を検査し、今後の適応を決定する
- 成果のプレゼン＋ディスカッションを行う

##### スプリントレトロスペクティブ
- ふりかえり
- 開発全体の検査
- KPT
    - Keep
    - Problem
    - Try

#### スクラムの成果物
##### プロダクトバックログ
- プロダクトレベルのやることリス

##### スプリントバックログ
- スプリントレベルのやることリスト
- 解像度は高い
- スプリントゴールが含まれる

##### インクリメント
- プロダクトゴールのための階段
- スプリントレビューで検査される
    - ユニットテストが出来ているかなど

# アジャイルになるために
## 成熟度モデル
1. ゴールが見えない・不信感・仲が悪い
1. みんなで頑張る雰囲気
1. 仕事がなんとか回りだす
1. 仕事を進め改善も出来る
1. DEVアジャイル
1. BIZアジャイル
1. 全員リーダー
1. アジャイルに「なる」

Not doing agile, but be agile.
アジャイルをするよりアジャイルになる
COPILOTにMATLAB Functionの中身を書いてもらった【Simulink】

# このページについて
以下のようなことをSimulinkでやりたいと思ったんだが、どうも通常のSimulinkのブロックだと作りづらい。
ってことで、Matlab Functionを使うことにした。ただ、自分で書くのは面倒くさいので、COPILOTに書いてもらった。

### ★やりたいこと★
・2入力1出力のMatlab Functionブロック中身を作りたい。
・入力1の過去Nサンプリング分の平均値を出力するようなMatlab Functionブロックを作りたい。（つまりFIRフィルタ）
・パラメータNについては、入力2で規定できるようにしたい。

# COPILOTにMATLAB Functionの中身を書いてもらった
↑で書いた"やりたいこと"をCOPILOTに伝えたら、一瞬で以下のようなコードを書いてくれました。

```matlab
function y = movingAverage(u, N)
    % 持続的なメモリを持つ変数
    persistent samples;
    persistent index;
    persistent sum;

    % 初期化
    if isempty(samples)
        samples = zeros(N, 1); % Nサンプル分の配列をゼロで初期化
        index = 1; % インデックスを1で初期化
        sum = 0; % 合計を0で初期化
    end

    % サンプルの更新
    sum = sum - samples(index) + u; % 古いサンプルを引いて新しいサンプルを足す
    samples(index) = u; % 新しいサンプルを配列に格納

    % インデックスの更新
    index = mod(index, N) + 1; % インデックスを循環させる

    % 出力の計算
    y = sum / N; % 平均値を計算して出力
end
```

# Simulinkブロック図
こんな感じで作りましたわ。
処理周期は0.01[s]にしました。入力は、5[rad/sec]のサイン波。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3700895/dc2d952c-7621-a842-4f17-4f5bea27a901.png)



# Simulation結果
なんか出来てるっぽい。。。
黒が入力信号で、青が出力信号ですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3700895/cf792eef-41ea-82ea-9014-9c20cc2b9867.png)



# 感想
COPILOT、悪くないっすね。
ABC353回答メモ

# 0.はじめに
　珍しく一日外出しており、疲労困憊で参加。
 そのせいか、相性が悪かったのか、C以降が解けず
 ひさびさの2問のみの正解。
　とはいえ、みんな芳しくなかったのか、レートは-12で済みました。


# 1.A - Buildings
　問題文はややこしめでしたが、実装すると楽な感じでした。
 一つ目のビルより高いビルがあるかを
 2つ目以降順にみていきあったらその位置を出力して終了
 なかったら-1を出力して終了。
 で、AC頂きました。

　https://atcoder.jp/contests/abc353/submissions/53321164


# 2.B - AtCoder Amusement Park
　日常によくありそうなシチュエーションだったため考えやすかったです。
 【実装】
 　・スタートカウント変数Sを0で初期化
   ・現在の座席の空きNKをKで初期化
   ・以下A[i]（リストを先頭から一つずつ読み込む数）を順に処理
   　-A[i]がNK以下の場合（まだゴンドラに乗れる）
    　-NKからA[i]をマイナス
   　-A[i]がNKより大きい場合（もうゴンドラに乗れない）
    　-Sに1加算
    　-NKにK-A[i]をセット
   ・最後にS+1を出力して終了
   　(繰り返しの最後のゴンドラにだれか乗っているので)

　https://atcoder.jp/contests/abc353/submissions/53330684


# 3.C - Sigma Problem
　コンテスト中は正解できませんでしたが、解き方の方向性は
 あってたようです。実装がうまくいかずに限界を感じました・・・。
 解説の解答例を見て、出力方法が合点行きました。

 【実装】
 　1.変数ansに余りを取らなかったときの合計をセット
  　-ans=(N-1)×sum(A)
 　2.Aを昇順ソート
 　3.余りが発生する組み合わせ変数Mに0をセット
 　4.各数毎の余りが発生する限界位置変数mにNをセット
 　5.mod用変数pに10の8乗をセット
 　6.以下iを0～N-2まで繰り返し
  　-1.mにmとi+1の大きい方をセット
  　-2.以下m-1がiより大きいかつA[m-1]+A[i]がp以上の間
   　-1.mから1マイナスする。
    　(mを大きい方からずらしていき、A[i]と足した場合にpを超える
     　＝mod計算が必要な位置の最大　を探る)
  　-3.MにN-Mを加算
 　7.ansからp×Mを減算した値を出力して終了
 
　https://atcoder.jp/contests/abc353/submissions/53394600


# 4.D - Another Sigma Problem 
　Cが難しかったのでいったん見たけど、同じような難しさと思い
 Cに戻りました。
　解説を読んで、こちらの問題は最終的な合計のmodを取ればよい事が
 わかり、これは解けたかもな・・・と思いました。
 
 【考え方】
 　・リストの一番後ろの数をA[N-1]とすると、
  　A[N-1]を含む関数fの合計は以下となる
   　A[0]×(10のlen(str(A[N-1])))乗～A[N-2]×(10のlen(str(A[N-1])))の
    　合計
    上記を、A[N-1]～A[1]まで求めて合計し最後に998244353でmodを取って
    出力する

 解説の楽な実装が同じようなイメージ化と思います。

　https://atcoder.jp/contests/abc353/submissions/53396195


以上
AWS CLF-C02に合格できたのでやったことを書いてみる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194659/b97fb9c4-245c-c86e-2ac7-907a2c3f8834.png)
ギリギリの点数でしたが無事合格することができました。
勉強している方や興味がある方への参考になればと思いますm(_ _)m

### 1. プロフィール
　・年齢：20代
　・学歴：私文大学卒
　・職歴：もう少しで4年目に入るシステムエンジニア
　・AWSの実務経験：無し

### 2. 使用教材
　・[AWS Cloud Practitioner Essentials 日本語実写版](https://explore.skillbuilder.aws/learn/course/external/view/elearning/1875/aws-cloud-practitioner-essentials-japanese-ri-ben-yu-zi-mu-ban "AWS Cloud Practitioner Essentials 日本語実写版")
　・[【CLF-C02版】この問題だけで合格可能！AWS 認定クラウドプラクティショナー 模擬試験問題集（6回分390問）](https://www.udemy.com/course/aws-4260/?couponCode=JPLETSLEARNNOW "Udemy")

### 3. 勉強期間
　・１ヶ月半弱

### 4. 勉強方法
　**4-1. 「AWS Cloud Practitioner Essentials 日本語実写版」を１周する。**
    　　→　そもそもAWSがどういったものか、ITに精通していない方でもざっくりですが
    　　　知ることができておすすめです。

　**4-2. 「【CLF-C02版】この問題だけで合格可能！AWS 認定クラウドプラクティショナー 模擬試験問題集（6回分390問）」を繰り返し解く**
　　→　クセの強い問題もそこそこありますが、７割くらい解けるまで繰り返していきます。
 
:::note info
問題自体を解くことも大事ですが、選択肢に出てくる名称について理解することが重要と感じました。
:::

### 5. 実際に受けてみた感想
上記教材から同じような問題の出題は体感１割程ですが、９割以上は教材で見たことのある名称でした。
各名称の用途について理解しておけば合格圏内に入るかなと思います。
[Codespace] railsサーバー再起動方法

## 対象
GitHubのCodespaceを使って開発している方

## 前提
codespaceを立ち上げた状態でターミナルのコマンドで再起動します

## 手順
1. 起動中のプロセスIDを確認する
入力コマンド　※「$ 」はターミナルを意味するので入力は不要です
$ cat /workspaces/[リポジトリ名]/tmp/pids/server.pid
-> xxxxx(数字)
2. サーバーを停止する
$ kill -9 xxxxx　←手順1で取得したプロセスID
3. 再度サーバーを立ち上げる
$ rails server
【用語】Bounding Box、mAP、ROI、end-to-end、2ステージ検出、 Selective Search、Fast R-CNN、 Region Proposal Network (RPN)、Anchor box、アンカー、 ROI Pooling、ROI Align、インスタンスセグメンテーション

E資格用語の備忘録
シラバス2024 4.深層学習の応用 (2)物体検出 ⅰ.FasterR-CNN, MaskR-CNN

# Bounding Box
物体検出の結果として物体の位置や範囲を示す四角形の枠を指す。
コーナー2点による表現と、中心点と幅・高さを使う表現の2種類がある。

# mAP (mean Average Precision)
物体検出や画像分類などのタスクの性能を評価する指標の一つで、クラス単位の平均適合率（Average Precision）の全クラスでの平均(mean)を表す。
mAPcocoは、IoUが0.5~0.95までのmAPを平均したもの。

# ROI (Region of Interest)
ROIは、画像処理や物体検出において、特定の目的やタスクに関連する重要な部分を示す関心領域のこと。
ROIはBounding Boxで表される。

# end-to-end
システムやアルゴリズムが入力から出力までを一連の処理として直接扱うことを指す。

# 2ステージ検出
物体検出のアプローチの一つで、領域提案（候補領域の検出）と物体検出（クラス推定）を別々のステージで行う。R-CNN、SPPNet、Fast R-CNN、Faster R-CNN、RFCN、FPN、Mask R-CNNなどがある。精度高いが推論が遅い傾向。
1ステージ検出は、DetectorNet、SSD、YOLO、RetinaNet、CornerNetなどがある。精度低いが推論が早い傾向。

# Selective Search
領域提案の手法の一つで、物体検出のための候補領域を生成する教師なしアルゴリズム。（ディープラーニングでない）
R-CNNやFastで使用される。
計算コストが高く、パフォーマンスに影響を与えるため、Fast R-CNNの後継であるFaster R-CNNでは、より効率的なRegion Proposal Network (RPN)が導入された。

# Fast R-CNN
R-CNNの複雑な処理（関心領域ごとに畳み込み層へ通す）をやめ、画像ごとに一回の畳み込み操作を行うことで、計算量を大幅に削減した高速なアプローチ。

# Region Proposal Network (RPN)
ディープラーニングを用いた物体検出のアルゴリズムの一部であり、領域提案を生成するためのニューラルネットワーク。
Faster R-CNNで導入される。Mask R-CNNでも使用。
Selective Searchに比べて計算効率、学習の柔軟性、ディープラーニングの利用という点で優れている。

# Anchor box
各アンカーから基準の長さと縦横比をそれぞれ決めることで、複数のアンカーボックスを作り出す。
アンカーボックスは一つのアンカーに対して複数作られ、それぞれのアンカーボックスが物体を含むかどうかを推測する。

# アンカー
Anchorは、RPNにおける物体検出の基本的な要素であり、物体の位置と形状の初期推定を行う。
特徴マップ上にあり、これから描く矩形の中心の役割を果たす。

# ROI Pooling
畳み込み処理後の特徴マップから、異なるサイズのRoIを固定サイズの特徴マップに変換する。
後段の全結合層や分類層など固定サイズの入力を必要とするネットワークが統一された入力を受け取ることができ、物体検出の精度と効率性が向上する。
Faster R-CNNなどで導入される。

# ROI Align
ROI Poolingの改良版で、情報の欠落や位置合わせの誤差が生じる可能性を少なくする。
ピクセルレベルの補間を使用して、より正確な特徴の抽出と、特に小さなRoIや高解像度の画像での位置合わせの精度向上が実現。
Mask R-CNNなどのモデルで一般的に使用され、物体検出やセグメンテーションのタスクの精度とロバスト性の向上に貢献しています。

# インスタンスセグメンテーション
インスタンスセグメンテーションは、画像内の個々のオブジェクトをピクセル単位で識別し、それぞれに対してユニークな識別子を割り当てるタスク。
クラス単位でしか区別するセマンティックセグメンテーションと異なり、同じクラスでも個々の物体を区別することができる。
Mask R-CNN、YOLACT、DeepMask、PANetなどがある。
個人的なNet重大（１０大）News、Ethernet(82)

ネットワークプロトコルが専門です。
博士（工学）論文は、2005年９月、
端末間経路選択のための片方向遅延差測定方式(静岡大学)
です。

<この項は書きかけです。順次追記します。>
This article is not completed. I will add some words in order.
# Ethernet
Ethernetが成功したのは、DIX(Dec, Intel、Xerox)という発案企業だけでなく、当時のミニコンのTop Makerと、半導体のTop Makerが標準化に参加したことによるかなって思うんです。

次に、IEEEという世界で一番計算機、通信に関する学術団体で標準化したことと、
MACアドレスの登録をIEEEに委ねたことだろうと思います。

Ethernetを決めたIEEE 802委員会は、
その後、Wi-Fi(IEEE 802.11)
Bluetooth(IEEE (02.15)
にも広がっています。

Ethernet 記事一覧　Ethernet(0)
https://qiita.com/kaizen_nagoya/items/88d35e99f74aefc98794

15	EtherCATの品質管理(1)　
https://qiita.com/kaizen_nagoya/items/670c09a1122c9dc682f5

# TCP/IP

BSD



# Wi-Fi

無線網（Wi-Fi）空中線(antenna)(0) 記事一覧(209/300目標), Ethernet(51) 
https://qiita.com/kaizen_nagoya/items/5e5464ac2b24bd4cd001
# Bluetooth

# PPP

# Wireshark(旧名Ethereal)

# CAN

# softehter

『登大遊「SoftEther」』を知る　https://qiita.com/kaizen_nagoya/items/7a4062f845ebb2539e25

# Winny

# CXPI



# Reference
通信記事１００
https://qiita.com/kaizen_nagoya/items/1d67de5e1cd207b05ef7

プログラマが知っていると良い「公序良俗」
https://qiita.com/kaizen_nagoya/items/9fe7c0dfac2fbd77a945

資料集 [あなたもdocker私もdocker一覧] docker(0) to 166+61=227
https://qiita.com/kaizen_nagoya/items/45699eefd62677f69c1d

Error一覧 error(0)
https://qiita.com/kaizen_nagoya/items/48b6cbc8d68eae2c42b8

一覧の一覧( The directory of directories of mine.) Qiita(100)
https://qiita.com/kaizen_nagoya/items/7eb0e006543886138f39

＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
This article is an individual impression based on the individual's experience. It has nothing to do with the organization or business to which I currently belong.
# 文書履歴(document history)
ver. 0.01 add URL　20240510
### 最後までおよみいただきありがとう4ざいました。
いいね　💚、フォローをお願いします。
#### Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
Excelで和暦のフォーマットはgggyy"年"ではなくgggee"年"とすべき

## 「gggyy"年"」だとなぜ問題か？

Excelでは問題ないが、LibreOfficeで開くとyyの部分が西暦の末尾2桁と誤認識される
　→LibreOfficeでは、令和06年(西暦では2024年)の場合は、令和24年になってしまう。

Excelの場合でgggy"年"の場合は、令和6年になってほしいが、実際は令和06年になってしまう。
　→ggge"年"の場合は、令和6年となる。

### LibreOfficeの場合

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790322/74aefef9-9adf-0e91-5751-8fa1fc1cefb5.png)

### Excelの場合

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790322/00a5ba26-ef90-3e2b-8870-dbbbacc09ab5.png)

## 結論

互換性を意識し、和暦の場合はyやyyなどを使わない方がよい
以下の形式を使うべし
gggee
ggge
ggee
gge
gee
ge
Writing OS in Rustの写経が終わったので続けていじってみる

## 初めに
この記事では、最終的にWriting OS in RustとゼロからのOS自作入門を合体したようなOSが出来ることを目標としています。私は対してRustに詳しいわけでもOSに詳しいわけでもないただ面白そうというだけで来た人間なので理解がガバガバな面もあると思うので変なことを言っていたらコメントいただけると助かります。(失踪しないよう頑張ります)
[Writing OS in Rust](https://os.phil-opp.com/ja/)

### 1. UEFIブートへの対応
今回、Writing OS in Rustで使用していたbootloaderがバージョンアップによりUEFIブートに対応したとのことなので、これを利用したいと思う。

参考サイト群
* [移行ガイド](https://github.com/rust-osdev/bootloader/blob/main/docs/migration/v0.9.md)
* [ディスクイメージ作成](https://github.com/rust-osdev/bootloader/blob/main/docs/create-disk-image.md)
* [旧ブートローダードキュメント](https://docs.rs/bootloader/0.9.1/bootloader/bootinfo/index.html)
* [bootloader_apiドキュメント](https://docs.rs/bootloader_api/latest/bootloader_api/info/index.html)

#### やったこと

```
rustup component add llvm-tools-preview
```

[diff](https://github.com/ShotaKasuya/operating_system_in_rust/commit/307b8445a7502287ed3bc09d97a34d9f67d3a650)

今回、ディスクイメージ作成の項を読み我々が作成してきたosカーネルをサブプロジェクトに移し、新しく作成したプロジェクトからカーネルをコンパイル、qemuの起動を行う形式に移行した。

よくわからんエラー対処
`error[E0658]: use of unstable library feature 'proc_macro_byte_character'`
=> `rustup update`

一応qemuを実行することに成功はしたが、割り込みハンドラの扱いが変わっているため、どこかでエラーが発生し、色々あってトリプルフォルトでお亡くなりを繰り返していると思われる。これで環境構築が終わった。次回から、本格的にゼロから始めるOS自作入門の内容に入ろうと思う。

というかbootloader_apiのドキュメント見てるけどこれ文字出力できなくないか？俺はこれからどうやって文字を出力したらいいのだろうか...。

### 2. ピクセル描画(4章)

前回の状態だと何もわからずにブートを繰り返していたが、問題としては`println`が存在しないVGAテキストバッファに書き込もうとしてページフォルトを起こし、パニックハンドラにも`print`があるため結果としてリブートが起こったと思われる。
取り敢えず本で実装していない領域はコメントアウトしようと思うが、パニックしたことは知りたいのでパニックハンドラには`print`を残そうと思う。
ここでは、`BootInfo`の`Optional<FrameBuffer>`をラッピングする構造体を作った。
[BootInfo](https://docs.rs/bootloader_api/0.11.7/bootloader_api/info/struct.BootInfo.html)
```rust
# main.rs
    let BootInfo {
        framebuffer,
        ..
    } = boot_info;

    let frame_buffer_info = framebuffer.as_ref().unwrap().info();

    let mut display = Display::new(framebuffer.as_mut().unwrap().buffer_mut(), frame_buffer_info);

# display.rs
pub struct Display {
    buffer: &'static mut [u8],
    pub info: FrameBufferInfo,
}

impl Display {
    pub fn new(buffer: &'static mut [u8], info: FrameBufferInfo) -> Self {
        Self {
            buffer,
            info,
        }
    }
}
```
`Optional<T>`の扱いはこれで大丈夫かな?正直分かってないのでアドバイスあったらほしいです。
正直そのほかの実装で面白そうなところはないので大丈夫だと思います。
【Android】Retrofit2使用時の戻り値の比較 - Call vs Response

# Retrofit2の戻り値
戻り値の型として、以下の２つを想定し比較する
- Call\<T>
- Response\<T>

## APIの実行
### Call\<T>を使用する場合
APIの実行はCall\<T>クラスの以下のメソッドを使用することになる
- Call#execute()
    - 非同期処理
- Call#enqueue()
    - 同期処理

### Response\<T>を使用する場合
APIの実行は、APIの実行メソッドを呼び出すだけ
- APIの実行メソッドをsuspendメソッドにすることで非同期処理になる

## APIの結果の受け取り
- Call#excecute()を使用
    - Call#excecute()の戻り値であるResponse<T>から行う
- Call#enqueue()を使用
    - #enqueue()の引数Callback<T>のcallbackメソッドから行う
- Response\<T>を使用
    - 戻り値であるResponse<T>から行う

## 結論
- Response\<T>を使用する
- APIの実行メソッドをsuspendメソッドする
    - 非同期処理にし、スレッドをブロックしなくて済む

## 参考
- [Retrofit 2 – Synchronous and Asynchronous Calls](https://howtodoinjava.com/retrofit2/retrofit-sync-async-calls/)
- [Retrofit 2.6で通信を非同期処理](https://qiita.com/littleFeet/items/110a2a7237341feca804)
ラムダクロージャとは？ JavaScriptで状態を保持する関数を学ぶ

## はじめに
ラムダクロージャは、関数内で定義された変数の状態を保持する能力を持つ特殊な関数です。JavaScriptにおいて、ラムダクロージャはよく使われる概念の一つです。この記事では、ラムダクロージャの基本的な概念から実際のコーディングでの活用までを解説します。

## ラムダクロージャとは
ラムダクロージャは、外部のスコープから変数を参照する関数を指します。これにより、関数内で定義された変数の状態を保持し、関数が再度呼び出されたときに前回の状態を覚えておくことができます。これは、関数をオブジェクトとして扱う関数型プログラミングの一部です。

## ラムダクロージャの活用例

```js
function counter() {
    let count = 0;

    return () => {
        count++;
        console.log(count);
    };
}

let increment = counter();

increment(); // 1
increment(); // 2
increment(); // 3
```
この例では、counter 関数がラムダクロージャを返し、そのラムダクロージャが状態を保持してカウントを増やします。increment を呼び出すたびに、カウントが増えていきます。

## ラムダクロージャの利点
ラムダクロージャの利点は次の通りです。

- **変数の状態を保持**: 関数内で定義された変数の状態を保持し、関数が再度呼び出されたときにその状態を覚えておくことができる
- **クロージャの柔軟性**: 外部のスコープから変数を参照することで、関数内で動的な処理を実現できる
## まとめ
ラムダクロージャは関数型プログラミングにおいて重要な概念であり、JavaScriptなどの言語でよく使われます。関数内で状態を保持して柔軟な処理を行うことができるため、効率的なコーディングに役立ちます。
Reflex（Webアプリ作成ライブラリ）：バックエンドの仕組み（SSLはどうするのか？）

# ReflexのバックエンドはFastAPI + Uvicornで構成

Reflexのバックエンドは、FastAPIを使っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15972/bff33cd9-9317-5831-3606-6ef7c57d2b4c.png)


https://reflex.dev/docs/api-routes/overview/

FastAPI自体は、サーバではないので、Uvicornというサーバアプリを起動させます。
Uvicornの起動時に、FastAPIを利用して書かれたPythonのアプリコードをロードします。
Reflexは、Uvicorn実行コマンドをライブラリ内で定義して間接的に実行させています。

これは、FastAPIの仕組みなので詳しくは、そちらを参照してください。ネットでもたくさん情報がありますし、AIに質問してもよいと思います。

https://fastapi.tiangolo.com/ja/tutorial/first-steps/

FastAPIの起動コマンドは以下のようになります。（Reflexのコードとは関係ありません。）

- FastAPIを利用したPythonコード。

```py:main.py
from fastapi import FastAPI

app = FastAPI()


@app.get("/")
async def root():
    return {"message": "Hello World"}

```

- 上記のアプリをUvicornでWebアプリとして起動する。

```sh:run uvicorn
# mainはモジュール名、appはモジュール内にかかれたFastAPIのオブジェクト名
uvicorn main:app --reload
```

# Reflexのバックエンド起動方法

- Reflexライブラリの「reflex/utils/exec.py」というモジュールに、uvicorn起動処理が「run_backend、run_backend_prod」というメソッドで定義されています。

```py:reflex/utils/exec.pyのrun_backendの該当箇所のみ
    # Run the backend in development mode.
    uvicorn.run(
        app=f"{app_module}.{constants.CompileVars.API}",
        host=host,
        port=port,
        log_level=loglevel.value,
        reload=True,
        reload_dirs=[config.app_name],
        reload_excludes=[constants.Dirs.WEB],
    )

```

- 上記のコマンドが、「reflex run」によって起動され、バックエンドサーバが稼働します。

# SSLの設定

では、ReflexではHTTPSの有効化、言い換えると、SSLの設定はどうするのでしょうか？
Uvicornは、コマンド実行時に証明書ファイルを設定することでHTTPSを有効化できます。

```py
import uvicorn

if __name__ == "__main__":
    uvicorn.run("app.api:app",
                 host="localhost",
                 port=8432, 
                 reload=True,
                 ssl_keyfile="./key.pem", 
                 ssl_certfile="./cert.pem")
```

https://stackoverflow.com/questions/69207474/enable-https-using-uvicorn

ただ、ReflexのUvicorn起動コマンドを見る感じ、ReflexだけではSSLの有効化は難しいようです。
ですので、nginxなどのWebサーバをたてて、そちらでSSLの設定をするのが一般的のようです。

https://geniepy.com/blog/how-to-run-reflex-apps-in-production/

ちなみに、Streamlitは、Streamlit単体でSSLの設定ができます。
configファイルに記載することで可能です。

```toml:.streamlit/config.toml
[server]
sslCertFile = '/path/to/certchain.pem'
sslKeyFile = '/path/to/private.key'
```

https://docs.streamlit.io/develop/concepts/configuration/https-support

Reflexも同様の設定ができれば、nginxを構築する必要がなく楽なのにと感じます。社内で使うような簡単なものならWebサーバはいらない気もします。

Streamlitの方が先行してつくられている分、細かいところまで楽してできる配慮があります。
【AndroidStudio】AndroidGradlePluginのバージョンアップにはアシスタント機能を使うと便利

# はじめに
以前ご紹介した[SDKアップデート時に利用できるアシスタント機能](https://qiita.com/YuukiYoshida/items/bf3e9cd20b658c24fb6e)など、最近AndroidStudioがどんどん便利になっていますが、今回はAndroidGradlePluginのバージョンをアップデート時に利用すると便利なアシスタント機能をまとめてみようと思います。

# AGP Upgrade Assistant
正式名称はタイトルの通りになりますが、こちらはAndroid Studio 4.2から追加された機能になります。
これまでは【AGPとGradleのバージョンを変更】→【Sync Gradle Files】→【エラーやワーニングの指摘箇所を修正】→【Sync Gradle Files】→と何度も確認する必要があり大変でしたが、アシスタント機能を利用することで簡単にバージョンアップが行えるようになりました。

![スクリーンショット 2024-05-12 11.59.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354522/a278e15a-bb8b-f3fd-9805-54702d8a7aa9.png)

こちらのアシスタント機能を使用するには、メニューから　【Tools】→【AGP Upgrade Assistant】を選択するか、プロジェクト右下に表示されるバルーン、若しくはAGPの警告などから使用することが可能です。

アシスタント機能を表示すると、以下のように表示されます。

![スクリーンショット 2024-05-12 12.00.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354522/921df112-7ac5-6c48-8f5b-4fdfae5012ed.png)

上記表示内にて、アップデートするAGPのバージョンや関係するファイルの修正有無などを設定することが可能です。
必要な設定を行い、【Run Selected Steps】より一括して更新が可能です。

![スクリーンショット 2024-05-12 12.03.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354522/906f0d0e-f848-2edd-191d-8793d405ddc2.png)

更新が成功すると上記画面が表示され、更新に関する詳細と問題が発生した場合の差し戻しなどが可能です。

以上になります。

# さいごに
最近E-incで出してる電子ペーパーの凄さを知りました、そのうちラズパイで遊んだ内容を記事にできたら面白そうですかね。
Reactのレンダーについてちゃんと理解する

## Reactで描画されるためには

コンポーネントは画面上に表示される前にReactによってレンダーされ、その結果導き出された要素が画面上に描画されます。Reactでは描画までどのような手順で行われているのでしょうか。

:::note 
本記事ではReact日本語ドキュメントに合わせてレンダーというワードに統一しています。([参照](https://zenn.dev/yodaka/articles/7c3dca006eba7d))
:::

## 要素が描画される流れ

レンダーは以下のような流れで行われます。

1. レンダーのトリガー
2. コンポーネントのレンダー
3. DOMへのコミット

それぞれがどのような動作をしているか見ていきましょう

### 1. レンダーのトリガー

レンダーは以下のタイミングでトリガーされます。

- コンポーネントの初回レンダー
    - renderメソッドをコンポーネントに対して呼び出す
    - ルートコンポーネントを呼び出す
- コンポーネントのstate更新
    - コンポーネントのstateを更新すると自動的にレンダーがトリガーされる
    - stateの更新によってレンダーがトリガーされた関数コンポーネントを呼び出す

### 2. コンポーネントのレンダー

ReactにおけるレンダーはReactがコンポーネントを呼び出すことです。

レンダーは再起的に発生し、更新されたコンポーネントが他のコンポーネントを返す場合、次にそのコンポーネントをReactがレンダーするように再起的に行われ、ネストされたコンポーネントがなくなるまで続きます。

### 3. DOMへのコミット

レンダー間で違いがあった場合のみDOMノードを変更します。
レンダーが完了し、ReactがDOMを更新した後、ブラウザが画面を再描画します。
つまりレンダーと描画は異なる概念でドキュメントの中でも二つの概念は明確に区別されています。(レンダー≠描画)
更新されたコンポーネントは再レンダーされますが、実際に描画が切り替わるのは更新があったDOM要素のみとなります。

上記のような手順でコンポーネントの描画は行われます。どれだけコンポーネントが増えたとしても再起的に行われ、この手順が崩れることはないため、この手順を意識して開発をしていくことが重要になります。

## 参考資料

https://ja.react.dev/learn/render-and-commit

https://zenn.dev/yodaka/articles/7c3dca006eba7d
【MYSQL】内部結合と外部結合の違いと使い方

:::note warn
エンジニア初心者の投稿であるため、間違っている箇所が多くあるかと思います。
何かお気づきの点がありましたらご教授いただけると幸いです。
:::

## はじめに
MYSQLにある内部結合と外部結合。この2つの結合の違いが学んだ瞬間は理解できているが、少し時間が経つとそれぞれの結合の特徴や使い方がわからなくなってしまいます。今回、記事に書いてまとめることでアウトプットできたらいいなと思い、残させていただきます。

## 内部結合・外部結合とは

内部結合・外部結合についての説明はこの記事がすごくわかりやすかったのでおすすめです。それぞれの結合の詳細を知りたい方は確認してみてください。

https://wa3.i-3-i.info/word1262.html

内部結合・外部結合以外にも結合の種類があります。

## 内部結合

２つのテーブルを結合させて、1つのテーブルとして表示する方法です。
両方のテーブルで合体が可能なデータのみを取り出す。

## 外部結合

### 左外部結合

２つのテーブルを結合させて、1つのテーブルとして表示する方法です。
1つ目のテーブルを基準にして、それに2つ目のテーブルを合体していく。

### 右外部結合

２つのテーブルを結合させて、1つのテーブルとして表示する方法です。
2つ目のテーブルを基準にして、それを1つ目のテーブルを合体していく。

## 内部結合・外部結合早見表

文字で書くだけだと分かりづらいので実際に表を使ったそれぞれの違いを確認します。
結合では大きさカラムをもとにして結合を行います。

ポケモンテーブル [ テーブル1 ]
| 名前 | 大きさ |
| --- | --- |
| ピカチュウ | 小さい |
| イワーク | ちょっと大きい |
| リザードン | 大きい |

大きさ別特徴(偏見) [ テーブル2 ]
| 大きさ | 特徴 |
| --- | --- |
| 小さい | キュート |
| 大きい | エレガント |
| ちょっと小さい | クール |

### 内部結合の場合

内部結合では2つのテーブルで大きさカラムが一致したもののみを結合して表示する。

```bash
SELECT
【テーブル1】.【大きさ】,
【テーブル1】.【名前】,
【テーブル2】.【特徴】
FROM
　【テーブル1】
INNER JOIN
　【テーブル2】
ON
　【テーブル1】.【大きさ】 = 【テーブル2】.【大きさ】
```

| 大きさ | 名前 | 特徴 |
| --- | --- | --- |
| 小さい | ピカチュウ | キュート |
| 大きい | リザードン | エレガント |

### 左外部結合の場合

1つ目のテーブルを基準にして結合する。1つ目の大きさカラムが2つ目の大きさカラムにない場合は「NULL」と表示される。

```bash
SELECT
【テーブル1】.【大きさ】,
【テーブル1】.【名前】,
【テーブル2】.【特徴】
FROM
　【テーブル1】
LEFT OUTER JOIN
　【テーブル2】
ON
　【テーブル1】.【大きさ】 = 【テーブル2】.【大きさ】
```

| 大きさ | 名前 | 特徴 |
| --- | --- | --- |
| 小さい | ピカチュウ | キュート |
| ちょっと大きい | イワーク | NULL |
| 大きい | リザードン | エレガント |

### 右外部結合の場合

2つ目のテーブルを基準にして結合する。2つ目の大きさカラムが1つ目の大きさカラムにない場合は「NULL」と表示される。

```bash
SELECT
【テーブル2】.【大きさ】,
【テーブル1】.【名前】,
【テーブル2】.【特徴】
FROM
　【テーブル1】
RIGHT OUTER JOIN
　【テーブル2】
ON
　【テーブル1】.【大きさ】 = 【テーブル2】.【大きさ】
```

| 大きさ | 名前 | 特徴 |
| --- | --- | --- |
| 小さい | ピカチュウ | キュート |
| 大きい | リザードン | エレガント |
| ちょっと小さい | NULL | クール |



## おわりに
内部結合と外部結合について見てきました。早見表を作ったことによって、内部結合と外部結合の違いを素早く復習できるので、作って満足しています。結合は種類によって全く違うものを表示するので効果的に結合を使えるように日々思考錯誤したいと思います。

## 参考文献
https://wa3.i-3-i.info/word1262.html
Difyですぐ使えるテンプレート一覧(2024年5月版)

# DiFyとは
- 生成AIのアプリをGUIで手軽に作れる
- オープンソースで公開されている
- ローカル環境(パソコン＋Docker)や、有料ホスティングサービスで使える
- 公式ページはこちら https://dify.ai/jp

# 画面構成
- 「ワークフロー」で、左から右に流れるように、パーツ（処理)を置く
![screenshot_89.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142577/1b1bd8df-27d5-7429-58fb-ac88ac87ebf3.png)



# テンプレート
- テンプレートを使って、既存のサービスを簡単に呼び出せます
- 例： [Dockerで構築したDifyを利用しノーコードでRAGのチャットボットを作る](
https://qiita.com/sey323/items/8921bb767e2b0656f1cc)
    - （あらかじめ知識を与えておき、質問があるとその知識に沿った回答を行う）

# 最初から作成する場合
- 以下の4つのタイプの中から選んで作成します
    - チャットボット
        - チャット形式のアプリケーションを構築します。このアプリは質問と回答の形式を使用し、複数のラウンドの継続的な会話を可能にします
    - テキスト ジェネレーター
        - プロンプトに基づいて高品質のテキストを生成するアプリケーションを構築します。記事、要約、翻訳などを生成します
    - エージェント
        - タスクを自動的に完了するためのツールを選択できるインテリジェント エージェントを構築します
    - ワークフロー
        - 高度なカスタマイズが可能なワークフローに基づいて高品質のテキストを生成するアプリケーションを構築します。経験豊富なユーザー向けです




# 用意されているテンプレート
- 2024年5月12日時点で、28個のテンプレートが用意されています


## 執筆(3個)
- Fully SEO Optimized Article including FAQs
- Meeting Minutes and Summary
- Article Grading Bot

## プログラミング(5個)
- Website Generator
- Python bug fixer
- Code Converter
- Code Interpreter
- SQL Creator

## アシスタント(4個)
- Dify Feature Request Copilog
- Translation assistant
- Saas Startup Mentor
- Strategic Consulting Expert

## Agent(6個)
- SVG Logo Design
- YOuTube Channel Data Analysis
- Travel Consultant
- Investment Analysis Report Copilot
- Flat Style Illustration Generation
- Cyberpunk Style Ilustration Generater

## Workflow(9個)
- Workflow Plannning Assistant
- Question Classifier + Knowledge + Chatbot
- Knowledge Retreival + Chatbot
- ThreeStep Translation Workflow
- Text Summerization Workflow
- SEO Blog Generator
- Sentiment Analysis
- Email Assistant Workflow
- Customer Review Analysis Workflow

## 人事(1個)
- AI Front-end interviewer

# テンプレートやカスタムツールを自作できる？
- 独自の処理をひとまとめにして公開したいのですが、方法やガイドラインは見つけられませんでした
- API呼び出しぐらいは事例がありそうな気がします


# まとめ
- プログラミング無し、コードを書かずに生成AIを組み合わせて実行できると、夢が広がりますね！
【ChatGPT＋DALL-E3】連続で画像生成する方法。


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

　今回は、YouTuberのKEITOさんのショート動画から、連続で画像生成する方法を紹介します。　　　　

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

　昨日は、
　　日本各地で
　　　オーロラが観測されましたね。

　私は東京住まいなので、
　　見るのは、最初から
　　　諦めていました。

　動画で
　　見ただけです（夢がない😅）
***
　さて、本題です。

　YouTuberのKEITOさんの
　　ショート動画（X-Twitterポスト）
[5回連続で画像を生成する裏技](https://x.com/keitowebai/status/1789241113548865877?t=PKtrU1R0C64uEzfwqIK3ww&s=03)
　　　を紹介します。

　“5回連続で画像を生成する”って
　　どういうことなのか？

　ふつうは
　　指示すると、
　　　一枚（まれに二枚）の画像が
　　　　生成されます、

　ところが
　　この裏技を使うと、
　　　一度の指示で
　　　　五枚を連続して
　　　　　生成できるのです。
　　　　　（たまに四枚になりますが）

　ショート動画では
　　音声入力していますが、
　　　実際には、手入力になります。

　以下が
　　そのPromptになります。
```Text:5回連続で画像を生成するPrompt
（色）の猫が（何か）で遊んでるリアルな画像 を生成して。

（色）と（何か）は変数です。内容は任せます。

必ず1枚生成したら続けて生成して。5回続 けてください。
```

　二行目がキモですかね。
　　変数であることを伝え、
　　　その内容は
　　　　ChatGPTさんに
　　　　　決めてもらう。

　三行目で
　　繰り返させる。
　　　最初だけは
　　　　確実に生成させて
　　　　　連続性を担保している
　　　　　　のでしょうね。

　ここの
　　回数を変えることで
　　　生成枚数を変えられます。

　あまり多くを望まない方が
　　いいかと思いますけど。

　監視があるかは
　　知りませんけど、
　　　ロボット認定を受けるかも。
　　　　勝手な思い込みかと
　　　　　思いますけどね😅

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

　今回は、ここまで。
マジックメソッド①

## はじめに

### マジックメソッドとは

あらかじめ特定の役割を与えられたメソッド。
シグネチャ(名前、引数、戻り値の組み合わせ)と呼び出しのタイミングが決められていて、中身(機能)がないため、必要に応じて自分で実装する必要がある。

#### __getメソッド

未定義のプロパティを取得しようとした際

#### __setメソッド

未定義のプロパティを設定しようとした際

##### 参考コード

`to`, `subject`, `message`だけを定義しておいて、それ以外のプロパティは`__get`/`__set`メソッドで処理させている。


```php:MyMail.php
class MyMail
{
    public string $to;
    public string $subject;
    public string $message;

    private array $headers = [];

    public function __set(string $name, string $value)
    {
        $this->headers[$name] = $value;
    }

    public function __get(string $name): string
    {
        return $this->headers[$name];
    }

    public function send()
    {
        $others = '';
        foreach ($this->headers as $key => $value) {
            $key = str_replace('_', '-', $key);
            $others .= "$key: $value\n";
        }
        mb_send_mail($this->to, $this->subject, $this->message, $others);
    }
}
```

```php:get_set.php
require_once 'MyMail.php';

$m = new MyMail();
$m->to = 'test@example.com';
$m->subject = 'Test';
$m->message = 'Hello, World!';
$m->From = 'admin@example.com';
$m->X_Mailer = 'MyMail 1.0';
$m->X_Priority = '1';
$m->X_MSMail_Priority = 'High';
$m->send();
```

#### __issetメソッド

未定義のプロパティを`isset`関数で処理しようとした際

#### __unsetメソッド

未定義のプロパティを`unset`関数で処理しようとした際

##### 参考コード

```php:MyMail.php
class MyMail
{
    // 中略
    public function __isset(string $name): bool
    {
        return isset($this->headers[$name]);
    }

    public function __unset(string $name)
    {
        unset($this->headers[$name]);
    }
    // 中略
}
```

```php:isset_unset.php
require_once 'MyMail.php';

$m = new MyMail();
$m->From = 'admin@example.com';
var_dump($m->From); // 結果：string(17) "admin@example.com"
var_dump(isset($m->From)); // 結果：bool(true)
unset($m->From);
var_dump($m->From); // 結果：NULL
```

#### __callメソッド

未定義のインスタンスメソッドをコールした際

#### __callStaticメソッド

未定義の静的メソッドをコールした際

##### 参考コード

引数が渡されなかったらメソッド名に対応するキーの値を取得。
引数が渡されなければメソッド名に対応するキーに引数の値を設定。

```php:MyMail.php
class MyMail
{
    // 中略
    public function __call(string $name, array $args): mixed
    {
        if (count($args) === 0) {
            return $this->headers[$name];
        } else {
            $this->headers[$name] = $args[0];
        }
    }
    // 中略
}
```

```php:call.php
require_once 'MyMail.php';

$m = new MyMail();
$m->From('admin@example.com');
print $m->From(); //結果：admin@example.com
```
Codespaceが立ち上がらない エラー"Unable to start codespace. Please try again later"

## 事象
自分のリポジトリからcodespaceのブランチにアクセスした際発生。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3722781/44c268bf-26f9-4fc9-9096-307812e9867f.png)

## 解決方法
GitHub側の問題だったようです。
自分が気づいてから解決するまでは12時間ほどかかりました。
https://github.com/orgs/community/discussions/123358
SwiftUI disabledモディファイアの使い方

# disabledモディファイアとは
SwiftUIで利用されるViewのプロパティで、そのViewが無効になるかどうかを制御します。
具体的にはViewが無効化されると、ユーザーがそのViewを操作できなくなります。

ユーザーに対して操作が許可されていないことを明示的に示す場合や、特定の条件下でのみ操作を許可する場合などに便利です。



公式ドキュメント: 
https://developer.apple.com/documentation/swiftui/view/disabled(_:)

# disabledに辿り着いた背景
TextFieldが空の状態で、画面遷移するボタンを押したら警告の通知が表示されるようにしたい。


```swift:Swift
.onTapGesture {
         if inputText.isEmpty { 
             showAlert = true
             }
        }
```
上記の処理だけでいけるかと思いきや、
通常通りボタンが押されてしまい、アラートが表示されない...
何かがおかしい...

# 不具合の原因
Viewにdisabledモディファイアが付いていない為、ボタンが常に有効な状態のままとなっていました。
つまり、TextFieldが空であってもボタンをタップすることができてしまうということ。

いたって単純ですが、知らないと悩む箇所ですよね。

# 主な使い方

通常のViewに .disabled(true) もしくは .disabled(false) を設定することで、
そのViewを手動で無効化または有効化できます。


ボタンの場合、条件によってボタンを無効にすることがあります。
たとえば、今回のようにテキストフィールドが空の場合にボタンを無効にするといった場合です。

このような場合には、ボタンに .disabled(condition) を設定し、condition の値に応じてボタンを無効化するかどうかを制御します。

```Swift:Swift
Button("Submit") {
    // Submitボタンのアクション
}
.disabled(inputText.isEmpty) // inputTextが空の場合はボタンを無効化

```




# 参考記事
https://swappli.com/disabled-modifier/
Dayjsを使って時間表示を簡単にしよう！

# 1. はじめに
自分は10月よりAPPRENTICE SHIP(内定直結型エンジニア学習プログラム)のカリキュラムに２期生として参加しています。

https://apprentice.jp/lp

この記事はオリジナルアプリ開発の備忘録として書いています。
間違いがありましたらご指摘いただけると幸いです

# 2. 今回の内容
今回は、オリジナルアプリを開発する際に使用したDay.jsについて紹介します。
このライブラリを採用するまでは、JavaScriptの標準機能を使って日本時間と世界標準時（UTC）の時間差を計算していましたが、Day.jsを使うことで、その煩わしさから解放されました。
とても効率的に時間周りのことが実装できたので、共有したいと思います。

# 3. まずタイムゾーンとは？
タイムゾーンとは、地球を24の時間帯に分け、それぞれの地域で標準時を定めるシステムのことです。タイムゾーンを使用することで、地域ごとに異なる時間を一貫して管理することが可能になります。

### UTC (協定世界時)
- UTC（Universal Time Coordinated）は、グリニッジ標準時(GMT)から派生した世界標準時です。
- UTCは、国際的な時間調整の基準として用いられ、原子時計に基づいています。
### JST (日本標準時)
- JST（Japan Standard Time）は、UTCに9時間を加えた日本の標準時です。
日本国内では、この時間帯を基準としてすべての公式な時間が設定されます。

# 4. 簡単に変換してくれるDay.jsを使おう
Day.jsは、日付と時刻を操作するためのJavaScriptライブラリです。特にタイムゾーンの変換に便利な機能を備えています。

### 使わない場合のコード
JavaScriptのDateオブジェクトを使ってUTCとJSTを手動で変換する例：

``` js
// 現在のUTC日時を取得
const now = new Date();
const utc = now.toISOString();

// JSTへ手動で変換（UTC+9）
const jstDate = new Date(now.getTime() + (9 * 60 * 60 * 1000));
const jst = jstDate.toISOString();
```

### 使う場合のコード
Day.jsを使って、簡単にUTCとJSTを変換する方法：
``` js
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';

dayjs.extend(utc);
dayjs.extend(timezone);

// UTCの現在時刻を取得
const now = dayjs().utc();

// JSTへ簡単に変換
const jst = now.tz('Asia/Tokyo');
```
インポートなどで行数は増えてしまいますが、計算部分が省けたりと簡素にかけるのが分かると思います。

# 5. インストールとインポート
### インストール
Day.jsをプロジェクトに追加するには、npmまたはyarnを使用します：
``` bash
npm install dayjs
# または
yarn add dayjs
```
### インポート
Day.jsと必要なプラグインをプロジェクトにインポートします：

``` javascript
import dayjs from 'dayjs'; 
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';

dayjs.extend(utc);
dayjs.extend(timezone);
```

# 6. 書き方
- Day.jsを使った日付と時刻の操作方法の基本：

``` js
// 現在の日付と時刻
const now = dayjs();

// 特定のタイムゾーンでの日時
const timeInTokyo = now.tz('Asia/Tokyo');

// formatで形を指定
const formatTimeInTokyo = timeInTokyo.format('YYYY/MM/DD HH:mm');
console.log(formatTimeInTokyo); // 出力例: "2023/05/09 15:00"
```

### formatメソッドの使用時の注意点
formatメソッドは、日時を指定した形式に整形するために使用します。ここで使用する形式指定子には次のような意味があります：

- YYYY: 西暦年を4桁で表示します（例: 2023）
- MM: 月を2桁で表示します（例: 05）。Mを使用すると、先行する0がない形式で表示されます（例: 5）
- DD: 日を2桁で表示します（例: 09）。Dを使用すると、先行する0がない形式で表示されます（例: 9）
- HH: 24時間表記での時間を2桁で表示します（例: 15）
- mm: 分を2桁で表示します（例: 00）
#### その他の形式指定子
- ss: 秒を2桁で表示します（例: 00）
- a or A: AM/PM表記で午前または午後を表示します（例: AM, PM）

# 7. まとめ
今回はDayjsについて紹介させて頂きました。
フロントエンドで時間を表示するにはとても便利なものですね。
使い方としてはフォーマット以外にも、アプリ自体の国際化などにも活躍するそうです。
ぜひ、アプリ開発に活用してみてください！
Slackチャンネルを簡単に匿名投稿可能にする

:::note
[Anonymous Bot](https://opensay.co/)で簡単に匿名投稿は可能です！
無料プランではスレッドで匿名投稿することはできないです。
しかし、「話題を提供する一人目を匿名にするだけでも価値はある」と個人的に思いました！
:::

# 1. 背景
社内で「techshare」チャンネルがあります。

「techshare」チャンネルは技術的な情報を立場関係なく投稿できるチャンネルです。

現状以下の課題を感じています。
- 投稿する人に偏りがある
- 初めての投稿で一歩を踏み出すにはハードルが高い方もいるかも

そこで匿名投稿を可能にすることでチャンネルの投稿が活発化するのではと思い調査しました！

# 2. 公開されているBotを追加する

https://rainbow-engine.com/slack-anonymous-message/

こちらで紹介されている[Anonymous Bot](https://opensay.co/)を追加します。

## 2.1. Slackに追加

「Add to Slack for Free」をクリック

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3430353138322f62376438633636362d363562322d383630642d613438312d6233326165346332643630352e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405182/cd13438c-cd7e-e20a-1960-ea5f3bde8404.png)

「許可する」をクリック

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3430353138322f32313033326530332d656534362d383862662d323232302d3933343533326134306434332e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405182/8d0faec1-0246-31b8-e1ec-cd1680357307.png)

## 2.2. 匿名投稿にしたいチャンネルに招待する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405182/4683c616-7af2-4a88-c47a-1e79f69802da.png)

これでEnterを押すと以下のようにアプリの候補が出ますので、「Anonymous Bot」で「インストール」をクリックして下さい
既に入れてしまったので「表示する」になってます😅

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405182/791acc3c-c2fd-2fc0-a4f6-3bdcff08fde1.png)

## 2.3. 投稿する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405182/fa010e13-86c3-c5ca-93a3-dc520182bd04.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405182/9dabf9d6-f9f5-6e89-e4dc-b511f274d007.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405182/dd0a4c21-5e1c-272d-4073-a148c1281631.png)

投稿されました！

:::note
無料プランではスレッドで匿名投稿することはできないです😇
しかし、「話題を提供する一人目を匿名にするだけでも価値はある」と個人的に思いました！
1時間に投稿できる数は5個です
画像の投稿はできないそうです😇
:::

# 3. 最後に
- 「話題を提供する一人目を匿名にするだけでも価値はある」というのは個人的に大きな発見でした
- 次回は今回のBotでの無料プランの課題をカスタムボットで改善します！
Dockerで『簡単に』cronの定期実行を行う方法

# 概要
今回は使わなかったものの、自身の立ち上げてようとしているサービスでDockerのcronを定期実行する方法を試したので備忘録としてまとめてみようと思います。
※また、全体的に他のサイトはわかりずらかったのもまとめてみた理由の一つです💦

# ファイル構成
```
docker
 │  └── cron
 │       ├── config.json
 │       ├── Dockerfile
 │       ├── backup.sh
 │
 ├── buckup
 └── docker-compose.yml
```

# ファイルの内容
```docker-compose.yml
version: '3.8'

services:
  cron:
    container_name: 'cron'
    build:
      context: .
      dockerfile: ./docker/cron/Dockerfile
    # platform: linux/amd64 # 必要に応じて
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./docker/cron/config.json:/opt/crontab/config.json
      - ./backup:/backup
    environment: 
      PASSWORD: "${PASSWORD}"
```

```config.json
[
    {
        "schedule":"@every 1m",
        "command":"echo 'test1111' >> /backup/test.log"
    },
    {
      "comment": "1分毎 ログ出力",
      "schedule": "@every 1m",
      "command": "/scripts/backup.sh"
    }
]
```

```Dockerfile:Dockerfile
FROM willfarrell/crontab:latest

# Copy the backup script and config file into the container
COPY ./docker/cron/backup.sh /scripts/
COPY ./docker/cron/config.json /opt/crontab

# # Grant execution permissions
RUN chmod +x /scripts/backup.sh

```

```backup.sh
#!/bin/bash

# Set variables
# PASSWORD="${PASSWORD}"

# cron execute
echo 'test2222' >> /backup/test.log
```

# 結果
`buckup`フォルダの`test.log`ファイルに対して１分毎に
```
test1111
test2222
```
が出力されます。

# cronの詳細設定
現状、`config.json`にて1分毎に実行するように設定していますが、設定を変えればもっと色々なこともできます。詳細はドキュメントを見ていただければと思います。

#### ドキュメント

https://github.com/willfarrell/docker-crontab


# 参考になったリンク
Zenn

https://zenn.dev/bz0/scraps/4f1fa3ebcf1bc3

ドキュメント

https://github.com/willfarrell/docker-crontab
SourceTree(Revert)のやり方と実戦解説(Xcode)

# はじめに
SouceTreeでたまにマージしているけど、特定のコミットは含めたくない（削除したい）時などがあると思います！
そんな時に使えるRevertを振り返る為に備忘録として残します。

# 前提条件
- Souce Treeを日頃使っている方
- gitの知識がある程度ある方

#![スクリーンショット 2024-05-12 10.35.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348250/866ea58f-6cc0-08e4-786d-d7bcf39b3c9d.png)
 Revertとは
元々すでにマージされているコミットを削除してくれるくらいの感覚です！
色んな記事があるので正しい情報はそちらをみて頂けたらと思います。

# 実戦！

gitにリポジトリとXcodeの準備が終わっているところから進めていきます！

### 1
まずはxcodeとgitignoreあたりをgit管理します！

![スクリーンショット 2024-05-11 16.43.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348250/3de6fa95-a26d-3b5b-d4ef-3f707b3f6c9d.png)

### 2
これはrevertの振り返りなのでこんな感じで適当に変更します。
実際のプロジェクトだと何か機能を追加したり変更を加えたりすると思います。
![スクリーンショット 2024-05-11 16.46.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348250/bd8fc367-db5b-da6f-250e-003ebc941307.png)

### 3
そうするとuncommited changedになるので、commitしていきます。
この作業を何回か行います。
![スクリーンショット 2024-05-11 16.50.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348250/247615fa-4c06-fe0e-46a7-cfb1d3e89b4c.png)

### 4
このように変更のcommitが変更されていきますね。
(本来のプロジェクトだとブランチを切って行うと思いますがそこは省きます)

![スクリーンショット 2024-05-11 16.53.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348250/5e43852d-313f-48a1-4c1a-085811baf1c4.png)

ソースコードはこんな感じ
![スクリーンショット 2024-05-11 16.55.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348250/6ad7d324-0cbc-80c4-0d77-c0f2141c1f6f.png)


### 5　
それでcommit2のprint("revert 2.")を削除したいとします。その場合にRevertを行います！！

まず、commit2の位置でブランチを作成します。
![スクリーンショット 2024-05-11 16.58.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348250/7e75ce84-be94-e5ea-0f1e-c8dd373257bc.png)

### 6
先ほど作成したブランチの位置で２本指タップをし、「コミット適用前に戻す」を選択し、アラートが表示されるのでOKを選択!
これがRevert！！
[スクリーンショット 2024-05-12 10.08.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348250/17836694-c392-d547-21b0-df157d03ad0e.png)


![スクリーンショット 2024-05-12 10.06.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348250/1e47edef-f6ff-024a-dccf-a9e0f1af4251.png)

### 7
revertを行うと、revertしたものがcommitされます！

![スクリーンショット 2024-05-12 10.08.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348250/9bc8bac1-ede7-513d-c772-d46ac16c90e9.png)

revertした内容を確認するとprint("revert 2.")が削除されていることが分かると思います。
![スクリーンショット 2024-05-12 10.35.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348250/da2b70a1-dd6e-529d-1315-e88e0a584f2e.png)

### 8
今回はcommit2のみを削除してそれ以外は残したいので、ここからチェリーピックを使って修正していきます！

チェリーピックは変更を含めたいブランチにチェックアウトしておいて、そこから取り入れたいcommitを選択して、
二本指タップで「チェリーピック」を選択すればいけますね！コンフリクトした時はその都度修正しましょう！

# 最後に
revertあまり使わないので自分も分からなくなりました笑
これを機にrevert操作をマスターしちゃいましょう！