OmniAICreator/Qiita-1.07M huggingface dataset:
AWS認定SysOpsアドミニストレーター・アソシエイト受験談&学習法

## 概要
2024年5月19日にAWS認定SysOpsアドミニストレーター・アソシエイトの試験を受けて合格しましたので、学習したこと等を情報共有として書いていきます。
合格基準720点のところ799点で合格しました、、、う〜ん、微妙な点数ですね、とりあえず合格できたという感じです。
### 前提の知識と経験
まず今年の3月にソリューションアーキテクト・アソシエイト、4月にはディベロッパー・アソシエイトに合格しています。SysOpsアドミニストレーター・アソシエイトの範囲のサービスについては使ったことはありますが、触れたことがある程度かなと思います。
あと、この試験の直前に新入社員研修の講師としてAWSについて教えていましたので、いくつかのサービスを知らない間にハンズオンしていたのが良い経験になっていましたね。
### 学習期間
今回も大体1ヶ月くらいで、平日は1日２〜３時間、休日は５〜６時間くらいです。
実務で試験範囲のサービスを使っていれば、もう少し短い期間で合格できるかもしれません。
ちなみに同じ会社のMathew Chanさんは「数日間の準備」で合格できたらしいので、「マジか！」という感じですね〜こちらの記事を参考に→ https://note.com/mathew_chan/n/n9ec6ceaf2a08

### 学習教材
#### 1. AWS認定SysOps Administrator Associate（SOA-C02）試験 対策トレーニング
Udemyの動画教材で試験範囲のサービスを一通り網羅できますので、とりあえず試験勉強を始めるときに観るのが良いかなと思います。前回のディベロッパー・アソシエイトでもお世話になりました。
この動画教材だけでの合格は難しそうですので、他の教材も使った方が良さそうです。
https://www.udemy.com/course/aws-sysops-administrator-associate-c02

#### 2. AWS認定 SysOpsアドミニストレーター アソシエイト 模擬問題集＋詳解
こちらもUdemyで模試問題集です。解説がとても丁寧で、なぜ正解が不正解かを理解することができますので、本番試験間際まで見ていましたね〜こちらも前回のディベロッパー・アソシエイトでお世話になりました。
こちらの模擬を理解できていれば、合格できるのかなと思います。
https://www.udemy.com/course/soa-c02aws-sysops-2024

#### 3. ポケットスタディ AWS認定 SysOps アドミニストレーター アソシエイト
こちらの書籍はディベロッパー・アソシエイトでもお世話になったポケットスタディシリーズです。試験範囲を網羅しつつ、各サービスの詳細が記載されています。ただ、この書籍のみでの合格は、、、ちょっと難しいかなと感じるので、Udemyの模試の併用は必要かなと思います。
https://www.amazon.co.jp/%E3%83%9D%E3%82%B1%E3%83%83%E3%83%88%E3%82%B9%E3%82%BF%E3%83%87%E3%82%A3-AWS%E8%AA%8D%E5%AE%9A-SysOps-%E3%82%A2%E3%83%89%E3%83%9F%E3%83%8B%E3%82%B9%E3%83%88%E3%83%AC%E3%83%BC%E3%82%BF%E3%83%BC-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88-ebook/dp/B0BQLYNLJM

#### 4. AWS Skill Builder
公式模擬試験 (無料版)を解きつつ、試験範囲のサービスの動画を観ていました。本番試験の雰囲気が掴めるので、こちらでの勉強はオススメです。
https://skillbuilder.aws/jp

### 本番試験
レベル感は公式模擬試験 (無料版)と同等で、Udemyで模試問題集より簡単な感じがしました。ひねった問題はなく、サービスの基本が分かっていれば答えられそうです。実際にサービスの理解があやふやなところは、確信が持てないまま答えを選んで、それで間違っていたのかも知れないです。
あと変な問題がなく、配点外の問題が分からなかったですね〜ディベロッパー・アソシエイトは、「これ、配点外だろ」という問題に見当がつきましたが、今回は分からなかったです。
ですので、捨てる問題がなく120分の時間を使って、結構時間ギリギリでした。

## 最後に
今回もありがたいことに合格ができました。ソリューションアーキテクト・アソシエイトとディベロッパー・アソシエイトの勉強をしていたので、なんとかなるかと思っていましたが、難しかったですね。サービス名は重複して出てきますが、試験内容はSysOpsアドミニストレーター・アソシエイトの勉強をしないと回答できないかなと思いました。
とりあえずエンジニアリングの基礎を勉強しつつ、次の試験に備えていきます。
[k8s] FluxCDがGitHubにトークンではなくSSHで接続するようにしてみた

## はじめに

今回は FluxCD が GitHub に対して SSH でアクセスするようにする設定を行います。

## 手順

[公式ドキュメント](https://fluxcd.io/flux/installation/bootstrap/github/#bootstrap-without-a-github-pat)に SSH を使って接続する方法が記載されているので、それに従います。

以下のコマンドを使って bootstrap すれば SSH で接続できます。

```bash
flux bootstrap git \
  --url=ssh://git@github.com/<org>/<repository> \
  --branch=<my-branch> \
  --private-key-file=<path/to/ssh/private.key> \
  --password=<key-passphrase> \
  --path=clusters/my-cluster
```

以下、ハマったポイントです。

- SSH の URL はレポジトリの Clone に使う URL を指定しては**いけない**。ドキュメント通りのフォーマットで指定する
- private key へのパスは**絶対パス**で指定する。私は`/home/$(whoami)/.ssh/ed25519`と指定することでコードをコピペで使い回せるようにしました。

## なんで SSH なの？

FluxCD のドキュメントの一番上に書かれているコマンド(↓)に従うと、Flux は GitHub に対してトークンを使って HTTP でアクセスします。

```bash
flux bootstrap github \
  --token-auth \
  --owner=my-github-username \
  --repository=my-repository-name \
  --branch=main \
  --path=clusters/my-cluster \
  --personal
```

https://fluxcd.io/flux/installation/bootstrap/github/

実際、生成される`GitRepository`リソースの定義を見てみると、HTTPS の URL が指定されていることが確認できます。

```yaml
# This manifest was generated by flux. DO NOT EDIT.
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
  name: flux-system
  namespace: flux-system
spec:
  interval: 1m0s
  ref:
    branch: main
  secretRef:
    name: flux-system
  url: https://github.com/piny940/infra.git
```

ですが、これには以下の問題があります。

- トークンを使うと、トークンの有効期限が切れたときに FluxCD が使えなくなる

もちろん`Tokens (classic)`を使えばトークンの有効期限を「無制限」にすることはできますが、セキュリティ的にはあまりよくありません。

そこで、今回は SSH を使って FluxCD が GitHub にアクセスするように設定しました。

## 最後に

今回は FluxCD が GitHub に対して SSH でアクセスするように設定しました。
次回は Kubernetes の Staging 環境を整えていきたいと思います。

## 参考資料

https://github.com/fluxcd/flux2/issues/2029

https://fluxcd.io/flux/installation/bootstrap/github/#bootstrap-without-a-github-pat
PM理論ってなんじゃい

# PM理論
PM理論とはリーダシップを構成する「P機能」「M機能」の二つの機能であるという理論

らしい，よくわからん

::: note 
各機能が強い場合を大文字（P,M）、弱い場合を小文字（p,m）で表し、その組み合わせで4つのタイプにあてはめる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3534057/a4d5970a-6ca9-627b-5e99-73d7c1387740.png)
引用：応用情報技術者試験過去問道場　令和4年春期　問75　回答解説
:::

上の図のように，リーダシップを構成するらしい

まずは，それぞれの機能ごとに何を表しているか見てみる
## P機能（目標達成機能）
まずは，P機能（P は Performance）

目標達成機能ともいうらしい，お堅い説明は下の文章

::: note info 
計画立案、指示、叱咤激励などによってチームの生産性を高め、目標達成に向けてチームをけん引していく能力
:::

簡単に言うと，背中で語る，プレーで語る的なリーダやな

今時（令和），叱咤激励なんかする上司，おらん．見たことないわ
だいたい，指示だけする人の方が多いと思わん？

それはさておき，次はM機能

## M機能（集団維持機能）
M機能のM は Maintenance
集団維持機能ともいうらしい，お堅い説明は下の文章

::: note info
チーム構成員同士の人間関係を良好に保ち、チームワークを深める能力
:::

人間関係を良好に保つっていうのは，結局はみんなで話し合って，みんなでやっていきましょうみたいな．
一番何も決まらないタイプのリーダやん，と思ってしまう．



正直，この理論は１９６６年にミスミ ジュウジさんが提唱したものやから，古臭い気もするけど．今でも残ってるってことは大事なことなんやろう．

知らんけど

オワリ

============================================================
モジュール変数を参照するのにリードオンリー指定ができないものかね

レガシーコードをリファクタリングすることがあるわけです。レガシーなので内部の挙動はよく把握されきっていません。部分的に把握できる特徴をプログラムでわかりやすく表現することが整理の方針となるわけですね。

よく見かけるのが、サブルーチンの引数が100個近い多数で、深いコールツリーの上から下まで多くの変数を連れ回すことです。昔はCOMMONブロックだったのだとしたら一応は改善なのかもしれませんが、サブルーチン毎に引数の順序・有無が微妙に違っていたり、呼び側とサブルーチンで変数名が違っていたりすると、もはやデータフローがひと目ではわからなくなってきます。

先日こんなやりかたをしてみたんですよね。

* 引数で連れ回されていた変数の定義場所をモジュールに移す
* 各サブルーチンでは、INTENT(IN) にできるものは引数渡しにして、値を変える変数はモジュールからの参照にする

もうちょっとスマートなやりかたがありそうなものだとは思うんですけどね。
【週末おそうじ】ローカルブランチをサクッと削除したい

# なにこれ
ローカルブランチがたくさん溜まってきたので削除したいなあと思って調べたコマンドをまとめた個人的なメモ。


# 特定のブランチを残して他の不要なブランチを削除する
### 残したいブランチが1つの場合
`develop` ブランチを残したい場合のコマンドです。
```zsh
git branch | grep -v "develop" | xargs git branch -d
```

### 残したいブランチが複数ある場合
`master` と `develop` ブランチを残したい場合のコマンドです。
```zsh
git branch | grep -v -e "master" -e "develop" | xargs git branch -d
```


# 全部のローカルブランチを削除する
おそらくこのケースはあまりないように思いますが、とりあえずコマンドを書き残します。
```zsh
git branch | xargs git branch -d
```


# マージされていないブランチを強制的に削除する
`-d` オプションを `-D` に変更すると強制削除になる模様。
以下にサンプルコマンドとして `develop` ブランチを残して他のローカルブランチをすべて削除したケースを書きます。
```zsh
git branch | grep -v "develop" | xargs git branch -D
```


# 最後に
使っていないブランチはどれが何のブランチなのかわからなくなってくるので、定期的にお掃除したいですね。
仕事では全然やってないけど、個人的な趣味でやっている開発は週末くらいしかやらないので忘れやすいし、たまに整理したい。
Node-RED Matter Pluginを試してみた

# はじめに

スマートホームの新標準「Matter」のTypeScript/JavaScript実装であるmatter.jsをNode-REDで動かしてみます。

https://github.com/project-chip/matter.js/

https://github.com/FezVrasta/node-red-matter

# インストール

Node-REDをインストールして、「メニュー」→「パレットの管理」→「ノードを追加」から@node-red-matter/node-red-matterを追加します。

または、npmコマンドで@node-red-matter/node-red-matterをインストールします。

```bash
cd ~/.node-red
npm i @node-red-matter/node-red-matter
```

# Node-REDフロー

パレットに「Matter」カテゴリが追加されます。
「Matter Device Status」ノードをフローエディタに配置します。

![21.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/86a32887-dcf5-df5f-41b4-37751dcb8d46.jpeg)

「Matter Device Status」ノードを編集します。
「Matter Device」の編集ボタン(鉛筆マーク)を押します。

![22.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/00d25780-1553-62c4-b5b4-502f37ad78a1.jpeg)

「Matter Server」に名前を設定します。(例では「Node-RED」としました。)

![23.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/43965779-24c0-cecb-deaa-b77c5073a14a.jpeg)

![24.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/b2ab9ceb-3d22-959b-ebba-6c7f0000b610.jpeg)

下にスクロールすると、ペアリング用のQRコードが表示されていますが、表示が崩れているため、そのままでは読み込むことができませんでした。

![25.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/d6e3edc8-0fbb-574a-98bc-f921ca0aec07.jpeg)

ターミナル、または、テキストエディタに貼り付けて読み取ります。

![スクリーンショット 2024-05-19 22.13.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/ac0318d2-cc47-1f4b-00ad-7ec8aba1bb20.png)

Apple Homeにアクセサリとして登録します。

![IMG_6039.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/a976bf79-78e9-c8b4-f4fc-21b9ee91942c.png)

![IMG_6038.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/dfb2ec16-2bb8-5afe-869a-81c95c8f96dc.png)

「ON」「OFF」を操作すると、Node-REDフロー上のノードのステータス表示も「ON」「OFF」に変化します。

![26_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/086a0cb6-4b24-0bf6-dad7-70e627f46631.jpeg)

![26_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/01124a59-67d0-5d0a-f7aa-d1da455547ea.jpeg)

# ダッシュボードにステータスを表示

Node-RED DashboardにMatterデバイスのステータスを表示してみます。

## Node-RED Dashboardのインストール

Node-REDをインストールして、「メニュー」→「パレットの管理」→「ノードを追加」からnode-red-dashboardを追加します。

または、npmコマンドでnode-red-dashboardをインストールします。

```bash
cd ~/.node-red
npm i node-red-dashboard
```

## Node-REDフロー

「change」ノードとDashboardの「switch」ノードをフローエディタに配置します。

![27.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/c6343188-9aad-e61c-a5b7-a3a8980f729b.jpeg)

「change」ノードを編集します。
「Matter Device Status」ノードのステータス情報(msg.payload.status.on)をmsg.payloadにセットします。

![28.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/1de88c77-a677-4316-c637-e88725b4cd87.jpeg)

「switch」ノードは入力の値「true」または「false」によって、ダッシュボードのトグル表示が変わります。
Apple Homeの操作とNode-RED Dashboardの表示がリンクするようになります。

![29_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/23186a48-e2ad-3604-9537-91b878fbe996.jpeg)

![29_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/0689a8bc-149c-4972-be7a-a4eef5711184.jpeg)
ジェネリクス関数

## ジェネリクスとは
メソッドなどで使用される型が、実際に使う時に決定される機能のこと。

## 通常の関数の場合
下記のコードで、返却値を「おはよう」などの文字列を返したい場合、下記のコードの返却値の型はInt限定のため実現できない。
```
func test(param1: Int -> (Int) {
    return param1
}
let result = test(param1: 1)
print(result) // 結果: 1
```

## ジェネリック関数の場合
下記のコードだと、Sting型を引数に入れるとSting型が返却される。
先ほどのようにInt型を入れても、Int型が返却される。

＊ジェネリクスの型はT、U、V などが使用されることが多いらしい。
https://swift.codelly.dev/guide/%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AA%E3%82%AF%E3%82%B9/#%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AA%E3%83%83%E3%82%AF%E5%9E%8B-generic-types
```
func test<T> (param1: T) -> (T) {
    return param1
}
let result = test(param1: "おはよう")
print(result) // 結果: おはよう
```
383. Ransom Note

# 383. Ransom Note
magazineの文字列がransomNoteで構成されているかどうかのチェックだった気がする。。
辞書型の復習

```python
class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        wordDict = {}
        for i in ransomNote:
            wordDict[i]=ransomNote.count(i)
            ransomNote.replace(i,"")
        counter = 0
        for i in wordDict:
            if(i not in magazine or magazine.count(i) < wordDict[i]):
                counter += 1
        if(counter == 0):
            return 1
        else:
            return 0
```
Word VBA

# スクリーンショットをペーストした後にサイズを調整、そのままワードの作業が続けられるようにする。
```vb
Sub ResizeAndInsertReturn()
    Dim sel As Selection
    Set sel = Selection

    ' 縮小率を設定（40%）
    Dim scaleFactor As Single
    scaleFactor = 0.4

    ' 選択しているオブジェクトをチェック
    If sel.Type = wdSelectionInlineShape Then
        With sel.InlineShapes(1)
            ' オブジェクトのサイズを縮小
            .ScaleHeight = .ScaleHeight * scaleFactor
            .ScaleWidth = .ScaleWidth * scaleFactor
        End With
    ElseIf sel.Type = wdSelectionShape Then
        With sel.ShapeRange(1)
            ' オブジェクトのサイズを縮小
            .ScaleHeight factor:=scaleFactor, RelativeToOriginalSize:=msoFalse
            .ScaleWidth factor:=scaleFactor, RelativeToOriginalSize:=msoFalse
        End With
    Else
        MsgBox "選択しているオブジェクトがありません。"
        Exit Sub
    End If

    ' リターンキー（改行）を挿入
    sel.TypeParagraph
End Sub

```
モデリングの世界に再入門：ユースケース記述

# はじめに

UMLの基礎からしっかりと学び直し、プロジェクトで役立つ形にアウトプットしていきたいと考えました。
自分自身の理解を深めるとともに、同じような課題を感じている方々の一助となれば嬉しいです。

UML2.5.1の仕様書を読んだ個人的な見解ですので、おかしなところがあればご容赦ください。

詳しいモチベーションはこちらの記事をご参照ください。

https://qiita.com/tkmsk/items/0ff91acf7397f80ace0b

前回はユースケース図に関してまとめました。

https://qiita.com/tkmsk/items/3be81fa1034770dab66a

今回は、ユースケース記述に関してまとめていきます。

# ユースケース記述

## 概要

ユースケース記述は、利用者（ユーザー）の視点からシステムの振る舞い（＝システムがどのような機能を提供するのか）を記述し、具体的なシナリオを通じて要件を明確化するために使用します。

## 記述方法

ユースケース記述は以下のような表で記述していくことが多いです。

| ユースケース名 | ユースケースの名称 |
|-|-|
| アクター | 対象となる機能を利用するユーザー |
| 目的 | ユースケースを実行する目的や達成しようとする目標 |
| 前提条件 | ユースケースが開始される前に満たすべき条件 |
| 成功条件 | ユースケースが成功したときの状態 |
| 失敗条件 | ユースケースが失敗したときの状態 |
| 基本フロー | ユースケースの基本的な手順やステップを順序立てて説明 |
| 代替フロー | 基本フローに対する例外的な状況や分岐点を説明 |
| 拡張フロー | 基本フローや代替フローのさらに詳細な分岐を説明 |

## 記述例

ユースケース図のときに使用したユースケース図を使用して1つ例を示します。

| ユースケース名 | 引き出し |
|-|-|
| アクター | 顧客 |
| 目的 | 顧客が口座から現金を引き出す |
| 前提条件 | 顧客がATMにログインしている |
| 成功条件 | 顧客が指定した金額の現金を受け取る |
| 失敗条件 | 残高不足、システムエラーなどで引き出しができない |
| 基本フロー | 1. 顧客がATMにカードを挿入し、暗証番号を入力する。<br>2. 顧客が「引き出し」を選択し、引き出し金額を入力する。<br>3. システムが残高を確認し、金額を引き出す。<br>4. 顧客が現金を受け取り、カードを回収する。 |
| 代替フロー | 3a. 残高不足の場合、システムはエラーメッセージを表示する。<br>3b. システムエラーの場合、システムはエラーメッセージを表示する。 |
| 拡張フロー | - |

# さいごに

今回はユースケース記述に関してまとめました。
ユースケース図を作成するときはセットで作成することが多いと思うので、合わせて使っていきたいと思います。
ChatGPTの無料ユーザーがGPT3を強制的に使用できるようにするuserscriptを書いた

ChatGPTの無料版ユーザーでもGPT4oが無料で使えるようになりましたが、回数制限があるため、GPT4を使用する必要がないときにはGPT3.5を使いたい場面は多いと思います。

しかし、GPT3.5を使用するか、GPT-4oを使用するかは、会話の開始時点はは選択できないため、無駄にGPT-4oを使ってしまう場面も多いのではないでしょうか
今回はそれを解決するuserscriptを書いたので共有します。

```js
// ==UserScript==
// @name         A tool to forcibly use GPT-3.5
// @version      2024-05-19
// @description  強制的にGPT3を使用します
// @author       You
// @match        https://chatgpt.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=chatgpt.com
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    let use_gpt3_5 = true;
    document.addEventListener('keydown', function(event) {
        if (event.ctrlKey && event.shiftKey && event.keyCode === 51) {
            use_gpt3_5 = true;
            alert("GPT3.5を使用します")
        } else if (event.ctrlKey && event.shiftKey && event.keyCode === 52) {
            use_gpt3_5 = false;
            alert("GPT4を使用します")
        }
    });
    const original_fetch = window.fetch;
    window.fetch = (...args) => {
        if (use_gpt3_5 && args[0] === "https://chatgpt.com/backend-api/conversation") {
            const body = JSON.parse(args[1].body);
            body.model = "text-davinci-002-render-sha";
            args[1].body = JSON.stringify(body);
        }
        return original_fetch(...args);
    }
})();
```

このuserscriptを有効にした時点で、gpt-3.5が使用されるようになります。
gpt-4を使用したくなったらctrl+shift+4を押し、gpt3.5を使用したくなったらctrl+shift+3を押すとgpt3.5が使用されるようにいつでもスイッチできます。

追記:iOSの場合、ショートカットからChatGPTに質問するを選択し、新しいチャットを始める、をonにするとGPT-3を選択できるようです
Oracle Databaseの接続文字列について

Oracleの接続文字列は以下のような構造になっています

```
ユーザー名/パスワード@ホスト名:ポート/サービス名
```

例) sqlplusを利用して接続する場合

```
sqlplus HR/hrpassw0rd@localhost:1521/xepdb1
```

(必要になるたびググっており、時間のムダのため、自分用のメモとして残しておきます)

**環境情報**

```
C:\>sqlplus -V

SQL*Plus: Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
```


```
SELECT * FROM v$version;
```

|BANNER|BANNER_FULL|BANNER_LEGACY|CON_ID|
|:---|:---|:---|---:|
|Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production|Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production<br>Version 21.3.0.0.0|Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production|0|
RuboCopのExtensions(rubocop-rails)について詳しく調べてみた

# 概要
実務でRuboCopを以下の拡張Copをrequireして使っています。
今回はこの中からrubocop-railsについて、具体的にどんなCopが含まれているのか軽く調べてみました。
 - rubocop-rails
 - rubocop-rspec
 - rubocop-performance
 - rubocop-factory_bot

# 参考
RuboCopの拡張Copには、公式でメンテナンスされているものとサードパーティ製のものの２種類があります。
ちなみに上記の4つは全て公式のCopです。

 - 公式の拡張Cop
https://docs.rubocop.org/rubocop/extensions.html#official-extensions
 - サードパーティ製の拡張Cop
https://docs.rubocop.org/rubocop/extensions.html#third-party-extensions

スレッドセーフとか低レイヤーな部分は自信ない方も多いと思うので、[rubocop-thread_safety](https://github.com/rubocop/rubocop-thread_safety)とか助かるかもしれないですね。

# rubocop-rails
[rubocop-rails](https://docs.rubocop.org/rubocop-rails/)はRailsスタイルガイドに則った拡張Copです。
公式ドキュメントを軽くを目を通してみて、興味深かったもの、気づきのあったものをピックアップしてまとめました。
### Rails/ReversibleMigration
migrationがロールバック可能な実装になっているかどうかをチェックしてくれるCopです。本番環境だと、バグやらデータ整備漏れが原因で不完全な状態のデータが生まれてしまい、マイグレーションにこけたりする場合もあるため、ロールバックできることをRuboCopが保証してくれると安心感があります。

### Rails/DangerousColumnNames
既存メソッドを上書きしてしまうようなカラムが定義されていないかチェックしてくれるCopです。(例えばUserモデルにsaveという名前のカラムを定義すると、ActiveRecordのsaveメソッドを上書きしてしまう。)
### Rails/Presence
```ruby
a.present? ? a : nil
# ↓
a.presence

a.present? ? a : b
# ↓
a.presence || b
```
という修正を自動で行ってくれるCopです。
### Rails/TimeZone
`Time.now`や`Time.parse`、`to_time`等のメソッドは`application.rb`で設定したタイムゾーンを無視して、システム時刻を基準に結果を表示します。

```ruby
# システム時刻を基準に結果を表示するメソッド
Time.now
Time.parse('2015-03-02T19:05:37')
'2015-03-02T19:05:37'.to_time
```

このようなメソッドを`application.rb`のタイムゾーンに従って時刻を表示するメソッドに修正してくれるCopになります。
```ruby
# application.rbで設定したタイムゾーンに従って時刻を表示するメソッド
Time.current
Time.zone.now
Time.zone.parse('2015-03-02T19:05:37')
Time.zone.parse('2015-03-02T19:05:37Z')
```

### Rails/WhereMissing
紐づく関連レコードが存在しないレコードを検索したいときは
```ruby
Post.left_joins(:author).where(authors: { id: nil })
# と書かなくても

Post.where.missing(:author)
# と書けばよいそうです。
```
これを自動で修正してくれるCopです。

### Rails/WhereMissing
リレーション先のレコードの存在をチェックする場合、`where(条件).exists?`とexists?(条件​)の２通りの実装パターンがあります。このCopsでどちらのパターンで統一するかを指定することができます。(デフォルトはパターン1のwhere+exists?になります。)
```ruby
# パターン1(where+exists?)
Author.includes(:articles).where(articles: {id: id}).exists?

# パターン2(exists?)
Author.includes(:articles).exists?(articles: {id: id})
```

なおパターン1の場合はeager_load, パターン2の場合はpreloadとして振る舞うため、実行結果は同じでも実行されるクエリの内容、実行回数が異なります。
Linux環境？WSL2？Ubuntu？Windowsユーザーの備忘録1

# はじめに
プログラミングの学習を始める際の環境構築ですが、なんとなくフワッとした知識のままになっていたので、改めて調べ直しました。
# Linux環境について
- オープンソース
  - 豊富な情報がインターネット上にあるので、問題解決に役立てることができる
  - 開発コストを最小限に抑えることができる
- Linuxカーネル
  - ハードウェアとソフトウェア間のやり取りを管理する中心的な部分
# WSL2について
- 正式名称　Windows Subsystem for Linux 2
  - Windows上にLinux環境を実行できるようにするもの
  - Linuxディストリビューションをインストールできる（Ubuntu、Debainなど）
  - Dockerなどのコンテナ技術を利用してアプリケーションを実装できる
# Ubuntuについて
- オープンソースのソフトウェアプラットフォーム
  - コマンドを受け付けるプログラムのことをコマンドラインと呼び、Ubuntu（端末）、コマンドプロンプト（Windows）、ターミナル（Mac）となっている
  ※ 呼び方については、あまり重要視しなくてもよい印象
### 引用
[徹底比較！Linux vs Windows！結局なにが違うの？](https://www.geekly.co.jp/column/cat-technology/1902_016/)

[WSL2をインストールしよう ！WindowsでLinux環境構築を実現](https://and-engineer.com/articles/Y-LnkhAAACUAb9Z9)

# おわりに
記事を読んでいただき、ありがとうございました！
情報量は自分なりにある程度絞って記述させていただきました。
初めての投稿で、拙い点が多々あると思いますが、自分なりに復習して記事の内容を整理することができました。
Windouwユーザーの初学者の方々の少しでも参考になれば幸いです。
手動実行で GitHub Actions をテストする

# TL;DR

1. `workflow_dispatch` Webhook イベント発生時に実行されるよう設定する
2. 新しくブランチを作成し、ワークフローに変更を加えた上で push する
2. GitHub の Actions タブへ遷移する
2. ドロップダウンで先ほどのブランチを選択し、`Run workflow` をクリックする

# 詳解

https://docs.github.com/ja/actions/using-workflows/manually-running-a-workflow

## `workflow_dispatch` イベントで実行されるように設定
```yaml:deploy-hogehoge.yaml
name: Deploy Hogehoge

on:
    workflow_dispatch: ## この記述が必要
    push:
        branches:
            - main
            - prod

```

## 新しくブランチを作成して push
新しくテスト用のブランチを作成し、ワークフローの yaml ファイルに変更を加えたあと、コミット -> プッシュする。
コミット前に GitHub Actions 用のリンターを使ってワークフローの文法チェックをしてもいいかもしれない。

https://rhysd.github.io/actionlint/

```shell
> git sw -c feat/test-ghactions

(テストしたいワークフローの内容に書き換えてコミット)

> git push origin HEAD
```

## GitHub の Actions タブへ遷移
GitHub をブラウザで開き Actions タブへ遷移したあと、特定のワークフローを選択する。
![actions002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1504894/acde119e-9584-0cfd-eaf5-eb0c28efec0b.png)

そうすると、`This workflow has a workflow_dispatch event trigger.` という説明とプルダウンが現れる。
![actions001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1504894/3f500242-e912-d6bd-f393-8e0ce0d7f137.png)

## 先ほどのブランチを選択して `Run workflow`
そしたら、先ほど新しく push したブランチを選択し、
![action003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1504894/20070bd3-365d-0ae8-cc52-cc375d8e44d4.png)

`Run workflow` をクリックする。
![スクリーンショット 2024-05-19 20.42.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1504894/0d1ff46b-d7b8-2b75-7da0-b213b94dc4ad.png)

これでデフォルトブランチ (`main` とか) にマージしなくてもワークフロー変更時のテストを行うことができる。
![actions004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1504894/5d1dff7d-91f9-a34a-313d-69cecaffed03.png)

# おまけ
上述のようにワークフローが `workflow_dispatch` Webhook イベント発生時に実行されるよう設定しておけば、REST API を使用してワークフローを実行することもできるみたいなのでやってみる。

https://docs.github.com/ja/rest/actions/workflows?apiVersion=2022-11-28#create-a-workflow-dispatch-event

アクセストークンの発行が必要。
`workflow_id` はワークフローのファイル名でも代用可能とのこと。

```shell
curl -L \
  -X POST \
  -H "Accept: application/vnd.github+json" \
  -H "Authorization: Bearer <YOUR-TOKEN>" \
  -H "X-GitHub-Api-Version: 2022-11-28" \
  https://api.github.com/repos/OWNER/REPO/actions/workflows/WORKFLOW_ID/dispatches \
  -d '{"ref":"feat/test-ghactions"}'
```
【parallels】Appleシリコン搭載macOSにWindows homeを入れる

# 概要
<!-- 発端や概要を記載 -->
初投稿。高性能なM3 ProのMacbookを購入したので、winodws11 homeを導入しようと思ったが、意外と面倒だった話。

<!-- 各チャプター -->
<a id="#前提"></a>
# 前提
- Appleシリコンはarmアーキテクチャなので、Intel CPUの時と同様にVirtualBoxやBootCampでwindowsを起動することができない。
- デフォルト設定のParallelsでインストールできるwindows11はpro版のみ。homeは対応していない(なぜかは不明？)
- Mircosoft公式でダウンロードできるisoファイルはAMD仕様なので、Parallelsで動作しない



<a id="#結論"></a>
# 結論
[UUP dump](https://uupdump.net)を使用して、arm版のisoファイルを作成する。方法は以下の動画
https://www.youtube.com/watch?v=C5is4jfjoEQ
で非常にわかりやすくまとめられていた。


<a id="#その他"></a>
# その他
- UTMを用いてwindows11(AMD)の動作も試したが、あまり快適ではなかったのでお勧めしない。
- Parallelsで作成したwindows11には当然ライセンス認証が必要。そのため、新しくwindows11のライセンスを購入するか、過去に使用していたライセンスを引き継ぐ必要がある。
- Parallelsでのwindows11の動作は非常に快適。ほかにもubuntuやKali linux、macOSなどもマウント可能。ただし、どれもarm仕様なのでwindowsのWSLと同一の環境を構築出来ないのが難点。

以上
Whisper英語動画の翻訳比較

スティーブ・ジョブズの2005年に行われたスタンフォード大学卒業式スピーチをこちらの方法にて、動画から文字起こしを行いました。Whisperを使用しています。

https://qiita.com/Noble_Laurel031212/items/4d4803ec6adb69651a35

Whisperは英語でも日本語訳に自動変換してくれるのですが、自動変換版と、英語版のままと、どちらの精度が高いのかを実験をしてみました。

スピーチ中盤あたりの話から抜粋します。

## Whisperで日本語に自動変換した版

私の2つの話は、愛と失敗についてです。私は幸せでした。私は、人生の初めに何かをやりたいことを見つけました。私は、20歳の時、ワズとアップルを始めました。私たちは、10年間、アップルは、2人の人とガラージュに入って、2億ドルの会社に入って、4000人の人を入れて、私たちは、1年前にマキントシを作ったことを発表しました。私は、30歳の時に、マキントシを作ったことを発表しました。私たちは、30歳の時に、マキントシを作ったことを発表しました。そして、私たちは、アップルを始めました。あなたが始めた会社から、どのようにやられますか？アップルが成長したとき、私たちは、私たちの会社を作る人を担当していました。そして、私たちの会社を作り始めた1年間、私たちは、良いことが起きました。しかし、私たちの未来のvisionは、逆転し始めました。そして、私たちは、落ちてしまいました。私たちは、私たちの会社のディレクターを彼と一緒に担当しました。そして、私たちは、30歳の時に、私たちは、公開的に出ていました。私たちの全ての大人の生活のフォーカスは、私たちの前に行きました。

## Whisperで英語のまま文字起こし後、ChatGPTにて直訳

私の2つ目の話は、愛と失敗についてです。私は幸運でした。私は若い頃にやりたいことを見つけました。ワズと私は20歳の時に両親のガレージでアップルを始めました。私たちは一生懸命働き、10年後にはアップルはガレージの2人から4,000人以上の従業員を持つ20億ドルの会社に成長しました。1年前には最高傑作であるマッキントッシュを発表しました。そして、私は30歳になりました。そして、私は解雇されました。どうやって自分で始めた会社から解雇されるのでしょうか？アップルが成長するにつれて、私は会社を一緒に経営するために非常に才能のある人物を雇いました。最初の1年間はうまくいきましたが、私たちの将来のビジョンが次第に分かれ始め、最終的には対立しました。その結果、取締役会は彼の側につきました。そして、30歳で私は退任し、非常に公に退任しました。私の成人期の全ての焦点が失われました。それは壊滅的でした。数ヶ月間、私は何をすべきかわかりませんでした。私は前の世代の起業家たちを失望させたと感じました。バトンを渡されたときにそれを落としたのです。私は非常に公の失敗者であり、シリコンバレーから逃げることさえ考えました。しかし、何かがゆっくりと私に芽生え始めました。私はまだ自分のしていたことを愛していました。アップルでの出来事はそれを一片も変えませんでした。私は拒絶されましたが、それでも私は恋に落ちていました。だから、私はやり直すことに決めました。その時は見えなかったのですが、アップルから解雇されたことは私にとって最良の出来事でした。成功する重さが、新たに始める軽さに置き換えられました。それは私を人生で最も創造的な時期に導きました。

## 結論

「餅は餅屋」ということかもしれませんが、やはり外国語の時は外国語のまま文字起こしをして、翻訳は生成AIなりDeepl翻訳を使うなど、ワンクッションあった方が翻訳の正確さは高くなりそう、という結果でした。
【macOS】Rosettaを使用するターミナルを複製するシェルスクリプト

Appleシリコン搭載のmacでは，X86-64アーキテクチャのみで動作するソフトウェアをターミナル上で実行するためには，「Rosetta2を使用して開く」設定が必要となります．

以下のシェルスクリプトで，デフォルトアプリケーションのターミナル（ARM製）を複製し，X86-64専用のソフトを動かす用のターミナルを作成します．

```
#!/bin/bash

# ターミナルのパス
ORIGINAL_APP="/System/Applications/Utilities/Terminal.app" 

# 複製先のパス
DUPLICATED_APP="/Applications/Utilities/複製ターミナルの名前.app"

# ターミナルの複製
sudo cp -R "$ORIGINAL_APP" "$DUPLICATED_APP"

# 複製ターミナルにてRosettaで開く設定を行う
sudo /usr/libexec/PlistBuddy -c "Add :LSApplicationHasRosetta2Execs bool true" "$DUPLICATED_APP/Contents/Info.plist"

```

複製したターミナルのアイコンを自分の用意したアイコンに変更する処理も実装したかったのですが，色々試しても変更されず...

とりあえず複製だけできればいいか．．．
[React] Create React App(CRA)を使用したReactプロジェクトのフォルダ構成

# 目次（生成されるファイル）
- [node_modules](#node_modules)
- [public](#public)
- [src](#src)
- [gitignor](#gitignor)
- [package.json](#package.json)
- [README.md](#README.md)
- [package-lock.json](#package-lock.json)

# node_modules
- プロジェクトで使用されるすべての依存パッケージが格納されます。

# public
- 公開用の静的ファイルが格納されます。
- `index.html`: アプリケーションのルートHTMLファイルです。このファイルにReactコンポーネントがレンダリングされます。

# src
開発者が実際にコーディングするファイルが格納されます。
- `index.js`: アプリケーションのエントリーポイントです。ReactDOMを使ってReactコンポーネントをDOMにレンダリングします。
- `index.css`: アプリケーション全体のスタイルシートです。
- `App.js`: メインのReactコンポーネントです。アプリケーションの基本的なUIを定義します。
- `App.css`: `App.js`コンポーネントのスタイルシートです。
- `App.test.js`: `App.js`のテストコードです。
- `setupTests.js`: テストの設定ファイルです。

~~~:ex_folda_structure
├── public/
│   ├── index.html
└── src/
│   ├── index.js(index.jsx)
│   ├── index.css
│   ├── App.js(App.jsx)
│   ├── App.css
│   ├── App.test.js
│   ├── setuoTest.js
│   └── components/
│       ├── Button/
│       |   ├── Button.js(Button.jsx)
│       |   ├── Button.css
│       |   └── Button.test.js
│       └── Form/
│       │   ├── Form.js(Form.jsx)
│       │   ├── Form.css
│       │   └── Form.test.js
~~~

# gitignor
- Gitで管理しないファイルやディレクトリを指定するファイルです。

# package.json
- プロジェクトの依存パッケージやスクリプトを管理するファイルです。

# README.md
- プロジェクトの概要や設定手順などの説明が記載されるファイルです。

# package-lock.jso
- 正確な依存関係ツリーを記録するファイルで、再現性のあるビルドを保証します。

# 参考リンク
- [プログラミング初心者のための入門ブログ](https://dev-k.hatenablog.com/entry/create-app-hatenablog)
2年目エンジニアの情報処理安全確保支援士対策 〜情報セキュリティマネジメント〜

どうもこんにちは。2023年4月から新卒でSIer上場企業で働いております、sirroと申します。
昨年10月にデータベーススペシャリスト試験に合格し、今年は10月に情報処理安全確保支援士試験の合格を目指しています。

というわけで本記事では、情報処理安全確保支援士試験対策として出題範囲に必要な知識についてまとめていきます。
今回は「情報セキュリティ」に絞って執筆いたしました。

本記事の内容については、こちらの参考書を基に記載しておりますので、当参考書も是非ご購入して学習の効率を高めてください。

https://x.com/DB_sirro_SE/status/1780603983209599146


# 1.情報セキュリティマネジメント

### 情報セキュリティポリシに基づく情報の管理
・・情報セキュリティ対策として、何をどのように守るのか明確にするために、情報の機密性や完全性、可用性を維持していくための組織の方針や行動指針をまとめた情報セキュリティポリシを策定する。

### 情報セキュリティインシデント
・・情報セキュリティを脅かす事件や事故。
### 情報セキュリティ事象
・・情報セキュリティインシデントの他に、情報セキュリティに影響を与えるかもしれない状況のこと。

### 情報セキュリティポリシの基本構成
①情報セキュリティ方針・・情報セキュリティに対する組織の基本的な考え方や方針を示すもので、経営陣によって承認される。目的や対象範囲、管理体制や罰則などが記述。
②情報セキュリティ対策基準・・適切な情報セキュリティレベルを維持・確保するための具体的な遵守事項や基準を定める。

### ISO/IEC 27000ファミリー規格

・ISO/IEC 27001:2022 (JIS Q 27001:2014) ・・・組織がISMSを確立、導入、運用、監視、レビュー、維持し、継続的に改善するための要求事項を規定している。
・ISO/IEC 27002:2022 (JIS Q 27002:2014) ・・・情報セキュリティ対策のベストプラクティスとしてさまざまな管理策が記載されている。
・ISO/IEC 27014:2020 ・・・情報セキュリティのガバナンスに関する規格。
・ISO/IEC 27017:2015 (JIS Q 27017:2016) ・・・クラウドサービスの情報セキュリティ管理策の実施に関する規格。

###事業継続計画(BCP)
・・災害や事故などの発生時、目標復旧時点(RPO)以前のデータを復旧し、目標復旧時間(RTO)以内に再開できるようにするために事前に計画を策定する。


# 2.リスクマネジメント

### 情報資産台帳
・・情報資産とその機密性や重要性、分類されたグループなどをまとめたもの。情報資産をもれなく記載するだけだなく、変化に応じて更新していく。

### リスク
・・まだ起こっていないが、もしそれが発生すれば、情報資産に影響を与える事象や状態。すでに起こった事は問題として処理。

### リスクアセスメントのプロセス
①リスク特定・・リスクを発見して認識し、記述する。
②リスク分析・・特定したそれぞれのリスクについて、情報資産に対する脅威と脆弱性を考える。リスクの発生確率を求め、実際にリスクが起こった時の影響の大きさを考える。
③リスク評価・・分析したリスクに対し、どのように対策を行うか判断する。


### リスク対応の方法

1.リスクを取るまたは増加させる・・起こりやすさや結果をかえ、リスクを取るまたは増加させる。
2.リスクの回避・・リスクを生じさせる活動を開始または継続しないと決定することによってリスクを回避する。
3.リスクの共有・・一つ以上の他者とリスクを共有する。
4.リスクの保有・・情報に基づいた意思決定によって、リスクを保有することを受け入れる。

# 3.個人情報保護マネジメント

### OECD8原則
・・個人情報保護に関する8原則。
1.収集制限の原則
2.データ内容の原則・・個人情報は、必要な範囲内で、正確で完全で最新でなければならない。
3.目的明確化の原則・・収集目的は、収集時に特定されていなければならない。
4.利用制限の目的
5.安全保護の原則
6.公開の原則・・個人情報の取り扱いについて基本方針を公開する。
7.個人参加の原則・・本人の求めに応じて、回答を行わなければならない。
8.責任の原則

### 個人情報保護法

オプトアウト・・個人情報などの第三者への提供は原則可能で、提供してほしくない場合は本人が拒否を通知する仕組み。
オプトイン・・個人情報などの第三者への提供は原則不可能で、提供するためには本人の同意を得る必要がある仕組み。


# 4.法律、標準

### コンピュータ犯罪に関する刑法

1.電子計算機損壊等業務妨害罪・・人の業務に使用する電子計算機を破壊するなどして業務を妨害することを処罰する法律。
2.電子計算機使用詐欺罪・・電磁的記録を用いて財産上不法の利益を得る犯罪を処罰する法律。
3.不正指令電磁的記録に関する罪(ウイルス作成罪)・・マルウェアなどの不正な指示を与える電磁的記録の作成及び提供を正当な理由なく故意に行うことを処罰する法律。


### FIDO
・・標準規格化されたパスワードに変わる新しい認証技術。
⚫︎FIDO UAF・・生体認証などのシンプルで強固な本人確認手段によりパスワードを使わずに認証を行う。
⚫︎FIDO U2F・・サービスに強力な２番目の認証機を追加することで、既存のパスワードに追加してセキュリティを強化できる。
⚫︎FIDO2・・UAFとU2Fを統合した仕様。ブラウザから直接生体認証機器に認証要求を送ることを可能にしている。


# 5.監査、内部統制

### システム監査の手順

1.システム監査計画の立案・・実施するシステム監査の目的を有効かつ効率的に達成するために、監査手続の内容、時期及び範囲などについて適切な監査計画を立案。
2.システム監査の実施・・予備調査及び本調査を監査手続に従って行う。
3.システム監査結果の報告・・実施した監査についての監査報告書を作成し、監査依頼者に提出。


### システム監査技法
・ITF法・・稼働中のシステムにテスト用の架空口座を設置し、システムの動作を検証する。
・コンピュータ支援監査技法・・監査のツールとしてコンピュータを使用する監査技法の総称。


#
以上。今後も情報処理安全確保支援士について記事執筆予定なので、 Twitter、Qittaフォローお願いします。

https://x.com/DB_sirro_SE
【忘備録】CloudFlare KVではまった話

以前、Cloudflare KVを使用していた時、原因不明の謎のバグに悩まされ、原因を見つけるまでに時間がかかってしまったので忘備録として残しておきます。

以前、discordのbotを作っており、その中にゲームの機能も含まれておりました。
ゲームということで、複数のユーザーが一つのレコードに対して何度も読み書きをしていたのですが、ここでバグが起きてしまいました。
それはレコードを更新した後、レコードを読みだそうとしたときに何故か更新前の情報が返ってくることがある、というバグでした。
しかも不思議だったのは時間がたつと治る、という点でした。
その時の自分は(現在の自分もですが)、DBについて詳しくなかったため、何か実装を間違えていると勘違いし、バグを探していました。

しかし、原因はそこにあるわけではなく、Cloudflare KVの性質によるものでした。

https://developers.cloudflare.com/kv/reference/how-kv-works/

具体的には上記のページを読むとわかりやすいのですが、Cloudflare KVは世界各地にDBをクローンしており、ユーザーがデータベースを更新してから全世界のDBにその変更が伝わるまでに時間がかかります。
自分の要件の場合、`強整合性`というものが必要であり、Cloudflare KVを使うという選択肢が間違っていました。
とはいえ、Cloudflareで無料で使えるDBは少なく、Cloudflare D1という期間限定で無料で使えるデータベースに置き換えることにしました。
しかしながら、期間限定なのでいつかは有料になってしまい、いつかはまたデータベースを変更する予定でいます。

(ここまで注意して書いたつもりですが、間違ったことを書いていたらすみません)
【Android】キーボード表示

# はじめに
キーボードを表示する方法が調べたところ二つ出てきたので、どちらも調べ直さなくいていいようにメモがわりに記事にしておきます。


# 表示(Java)

```
binding.edtMessage.requestFocus();
InputMethodManager keyboardManager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
keyboard.showSoftInput(binding.edtMessage, 0);
```
または、
```
binding.edtMessage.requestFocus();
InputMethodManager keyboardManager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
keyboardManager.toggleSoftInput(1, InputMethodManager.SHOW_IMPLICIT);
```

# 表示(Kotlin)

```
binding.edtMessage.requestFocus()
val keyboardManager = requireContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
keyboardManager.showSoftInput(binding.edtMessage, 0)
```

または、
```
binding.edtMessage.requestFocus()
val keyboardManager = requireContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
keyboardManager.toggleSoftInput(1, InputMethodManager.SHOW_IMPLICIT)
```
ITパスポート 知的財産権

・著作権
文芸や美術、音楽、映像、コンピュータプログラムなどの創作物に関する権利
著作物を創作した時点から発生する
著作者人格権と著作財産権に分けられる

・コンピュータに関する著作物
プログラム言語やアルゴリズム、規約（プロトコル）は保護対象外
プログラムやマニュアル、ソフトウェア、Webページは保護対象

・産業財産権
特許庁に出願、審査、登録することで権利が発生する
・特許権
高度な発明を保護する
・実用新案権
考案を保護する
・意匠権
デザインを保護する
・商標権
マークを保護する
商品について使用するトレードマークと、役務について使用するサービスマークがある

・不正競争防止法
事業活動に有用な技術上または営業上の秘密として管理されている情報を保護する法律
・営業秘密
秘密として管理されているもの
事業活動に有用な技術または情報であるもの
公然と知られていないもの

・ソフトウェアと使用許諾契約
・アクティベーション
プロダクトIDと利用者のハードウェア情報を使って、ソフトウェアのライセンス認証を行う
・サブスクリプション契約
月額や年額で利用料金を支払い、常に最新のバージョンが利用できる契約
・シュリンクラップ契約
ソフトウェアの購入者がパッケージを開封することで使用許諾契約に同意したものとみなす契約

・ライセンス
ボリュームライセンス
大量購入者向けに、マスターを提供してインストールの許諾数をあらかじめ取り決める契約
サイトライセンス
特定の企業や教育機関などにある複数のコンピュータでの使用を一括して認める契約

・CAL
ソフトウェア製品ではなく、サーバのサービスにアクセスする権利を利用者に与えること

・DRM
音楽や電子書籍、映画などのデジタルコンテンツの著作権を守るための技術
・CPRM
１回だけ複製できるようにしたコピープロテクトの技術
・電子透かし（デジタル・ウォーターマーク）
デジタルコンテンツに、一見して分からないように著作権情報などを埋め込み、不正に利用された場合に検出できるようにするもの
OCIのチケット購入後から受験チケットのアクティベートまで（2024/5/19時点）

# はじめに
OCIの受験チケット購入後、試験予約ができるようになるまでの流れが無かったので整理。

※試験予約ができる状態になってからの説明は以下公式の内容を参照。
「認定試験受験ガイド（オラクル配信試験 - 監督付き) - 認定試験の予約や、受験の流れを説明します。
https://mylearn.oracle.com/ou/course/-/102867/153470

# （結論）言いたいこと
OCIの受験チケット購入後に、アクティベートが必要！しないと試験予約できない。

## 1.アクティベートするためのページを開く（担当：チケット購入者）
チケットの購入完了メールは来ない。
「Activate Your Oracle University Digital Learning Exam」（アクティベートしてください）のメールに、アクティベートするためのリンクがあるので押下。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2527830/ceb3bebb-30e5-b92c-5a8f-9530e79fd6c5.png)

## 2.該当する受験チケットの「Manage Attempts」（受験の管理）を押下（担当：チケット購入者）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2527830/a1dd8fb7-4ae7-b05f-903c-5bfc899d7c9c.png)

## 3.「Assign Exam Attempts」（受験への割り当て）を押下（担当：チケット購入者）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2527830/3fe710ff-d984-741b-f2f0-6be96643225c.png)

## 4.メールアドレスと受験回数を入力して「Add To List」を押下（担当：チケット購入者）
1回分のチケットを購入したのであれば、Number of Attemps（受験回数）は1。
メールアドレスは、チケットを割り当てたいOracleのアカウント（プロファイル）にする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2527830/8951f23c-e6db-798f-432f-6f4fcafccc97.png)

## 5.該当する個人にメールを送ってもよいです、にチェックを入れてSubmit（担当：チケット購入者）
割り当てたいOracleのアカウント（プロファイル）のメールアドレスが合っていることをきちんと確認してからSubmitする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2527830/5cdfd6c8-c246-0340-4b4d-b75154a3e834.png)

## 6.受験チケットの割り当て完了（担当：チケット購入者）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2527830/068c832b-a178-ddcb-7edb-657ae756fafd.png)

## 7.アクティベート実行！（担当：受験者）
割り当てたメールアドレスでMyLearnに実際にログインすると、アクティベートのページが強制的に表示されるのでアクティベートを実行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2527830/31a860fb-73d8-afdb-3a87-c10ea8e97777.png)

## 8.試験予約
あとは普通の公式通りの流れで。

## おわりに
受験チケットを購入する人と実際に受験する人が別なのかどうか、会社によるのかなぁ。
SharePointOnlineでaタグのtarget=_blankが効かない

先日、SharePointOnlineで以下のようなリンクが別タブで開かない現象がありました😢

```html
<!--開かない、、-->
<a target="_blank" href="https://xxxx.sharepoint.com/sites/xxx/SitePages/xxxx.aspx" >リンク</a>
```


原因としてSPOは既存のaタグの動作を書き換えてしまうようですので、以下のように属性を追加する必要があるそうです
```html
<!--data-interception="off"をつける-->
<a target="_blank" data-interception="off" href="https://xxxx.sharepoint.com/sites/xxx/SitePages/xxxx.aspx" >リンク</a>
```

これにより無事、別タブで開くことができました🙌
（なしてそういう仕様なの😥）

公式情報
[SharePoint Framework のハイパーリンクに関する考慮事項
](https://learn.microsoft.com/ja-jp/sharepoint/dev/spfx/hyperlinking)
『アウトプット大全』を読んだので、さっそくアウトプットしてみる。

## はじめに
読んだ本の感想や、得た知識を何かしらの形でアウトプットしたいと思った時に、調べて出てきたこの本を読み、アウトプットしない訳にもいかないので、さっそくアウトプットしたいと思います。
## アウトプットの基本
* ２週間に３回使った記憶は長期の記憶になる
* インプット３割、アウトプットを７割のバランス
* アウトプットしたら必ずフィードバックをするのが大事
## 伝わる話し方
* 誰かに話す際は自分の気づきや感想を加える
* クッション話法「Yes But」、「Yes And」、「Yes How」を使う
* 怒るのではなく、叱るのが大切
* 褒めるのはアウトプットであり、フィードバックでもあるため、褒めて伸ばすは理にかなっている
## 能力を引き出す書き方
* 書けば書くほど脳は活性化する（タイピングよりも手書きのようが良い）
* アイデアや気づきは３０秒〜1分以内にメモをする
* 絵や図を用いて視覚を使うと6倍以上記憶に残る
## 結果を出す人の行動力
* 教えることは最も効果的なアウトプット
* 人間の脳をコンピュータに例えると、記憶量は17.5TBと言われている（ウィキペディア１７個分）
* マルチタスクには向いていないため、ながら〇〇は非効率
* 物事の決断はわくわくする方を5秒で選ぶ
## あとがき
本の各チャプターごとにざっと書いてみました。
この本はチャプターの中でも１項目ずつ１〜２ページほどでまとめられているため、自分が気になったところから気軽に読むことができるようになっています。
この記事を読んでくれた方、アウトプットに悩んでいる方が居たら、是非読んでみてください。

学びを結果に変えるアウトプット大全
https://www.amazon.co.jp/dp/4801400558/
Ubuntu 24.04 LTS での aarch64 カーネルのコンパイルのやり方

# Ubuntu 24.04 LTS での aarch64 カーネルのコンパイルのやり方

[ここをクリックすると他の技術投稿の目次に行きます](https://qiita.com/FUKUTAKA7938/items/2312362e44dbcecd11ca)

#

カーネルバージョン 6.1.34 でやっています

参考サイト
[Emulating Raspberry Pi 4 with Qemu](https://gist.github.com/cGandom/23764ad5517c8ec1d7cd904b923ad863)

## ①コンパイラのインストール

※事前に make 等の通常コンパイラ関係は入れておいてください

### aarch64のパッケージの導入
`$ sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu`

私の環境での、上記のパッケージ関係以外なら
flex bison libssl-dev が 不足してました
なので、追加です。他に足りないものがあれば、
そのライブラリを入れておいてください。

`$ sudo apt install flex bison libssl-dev`

## ②カーネルのダウンロードとファイルの展開
### カーネルのダウンロード(バージョンは 6.1.34です)
`$ wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.1.34.tar.xz`
### ファイル展開
`$ tar xvJf linux-6.1.34.tar.xz`
`$ cd linux-6.1.34`

## ③コンパイル

### .config関係 の設定
`$ ARCH=arm64 CROSS_COMPILE=/bin/aarch64-linux-gnu- make kvm_guest.config`

### build
`$ ARCH=arm64 CROSS_COMPILE=/bin/aarch64-linux-gnu- make -j8`

途中で、止まったら、終了するまで
`$ ARCH=arm64 CROSS_COMPILE=/bin/aarch64-linux-gnu- make -j8`
を繰り返してください

ちなみにコンパイルには、結構時間がかかります

#
終わったら

~/ダウンロード/linux-6.1.34/arch/arm64/boot/に Image ができてると思います
このImage が カーネルファイルです

※上記の 「~/ダウンロード/linux-6.1.34/ 」の 箇所は、ダウンロードした場所または、コピーした場所などに変えて考えてください


#
参考サイト
[Emulating Raspberry Pi 4 with Qemu](https://gist.github.com/cGandom/23764ad5517c8ec1d7cd904b923ad863)


#
[ここをクリックすると他の技術投稿の目次に行きます](https://qiita.com/FUKUTAKA7938/items/2312362e44dbcecd11ca)
SSOに関するメモ

# 目的

業務でSSOについての知識が必要になったが、雰囲気しか理解してなかったので
まとめておく

# SSOって何？
- 一度の認証で複数のシステムやサービスにログインできる仕組み
# SSOは何がうれしい？
- サービスごとに異なるパスワードを覚えて、ログインして...みたいなことを考えなくてよくなり
パスワード管理の負荷が軽減される。またパスワードの使いまわしをなくしセキュリティを強化できる

# SSOの仕組み

## 登場人物
- IdP（ID Provider）：認証情報を提供する側
- SP（Service Provider）：IdPの提供する認証情報を利用しサービスを提供する側

## SSOを実現する方法
- エージェント方式
	- SPであるWebサーバに認証用のエージェントソフトをインストールする方式
	- エージェントからの認証情報をもとにSSOサーバが認証を行う
	- SP側の構成がかわるので社内システムやサービス提供側で実装する際の方式
 
> エージェント方式による認証の仕組み
> 
> 1. ユーザーがサービスAにアクセスし、ユーザーIDとパスワードを入力
>     
> 2. サービスA上のエージェントがサービスAに代わり、SSOサーバーに対し下記2点を確認
>     
>     - ユーザー本人であるか
>     - ユーザーがサービスAへのアクセス権限を持っているか
> 3. SSOサーバー側で認証情報を確認し内容に問題なければ、エージェントからユーザーに「認証済Cookie」を送信、サービスAの利用が可能
>     
> 4. ユーザーが別のサービスBにアクセス
>     
> 5. サービスB上のエージェントが、SSOサーバーに下記を確認
>     
>     - ユーザーがサービスBへのアクセス権限を持っているか
>     
>     - ※ユーザー本人であることは「認証済Cookie」があるため確認しない
> 6. SSOサーバー側で情報を確認し内容に問題なければ、サービスBの利用が可能
 
- リバースプロキシ方式
	- SPであるWebサーバの前段にリバースプロキシサーバーを設置し、リバースプロキシサーバーで認証を行う
	- SP側の構成がかわるので社内システムやサービス提供側で実装する際の方式
> リバースプロキシ方式による認証の仕組み
> 
> 1. ユーザーがサービスAにアクセスしようとすると、リバースプロキシサーバー経由でのアクセスとなり、認証画面が表示されるためユーザーIDとパスワードを入力
> 
> 2. リバースプロキシサーバー側で認証情報を確認し、内容に問題なければ、リバースプロキシサーバーからユーザーに「認証済Cookie」を送信、サービスAの利用が可能
> 
> 3.ユーザーがサービスBにアクセスしようとすると、リバースプロキシサーバー経由でのアクセスとなり、リバースプロキシサーバー側で「認証済Cookie」の情報を確認できればサービスBの利用が可能
 
- 代理認証方式
	- 代理認証用のエージェントがユーザーの代わりにIDとパスワードを送信してログインを完了させる方式。
	- SP側でなく、サービス利用者側でSSOを実現する方式
> 代理認証方式による認証の仕組み
> 
> ユーザーの端末に導入したエージェントの認証をSSOサーバーで実施
> 
> 認証に問題なければ、SSOサーバーからエージェントに対し、ユーザーが利用している各サービスのID・パスワード情報を送信
> 
> ユーザーがサービスにアクセスすると、エージェントが代理でID・パスワードを自動入力し、サービスの利用が可能

- フェデレーション方式
	- 異なるドメインのサービスでも認証情報を連携できる方法
	- フェデレーション方式では、パスワードではなく「チケット」と呼ばれる情報をユーザーとIdP（Identity Provider）がやり取りし、認証を行う
	- IdPとSP間で事前に信頼関係を構築し、IdPで認証された証を持って、SPへのアクセスを許可する
	- SAMLやOpen ID Connectなどのプロトコルで実現される

- 透過型方式
	- 比較的新しい方式らしく、あまり情報がなかった...
	- 詳しい人いたら教えてほしい

# 参考リンク

https://hogetech.info/security/sso/federation
https://www.ogis-ri.co.jp/column/themistruct/c106480.html
https://www.hitachi-solutions.co.jp/iam/sol_signon.html

SAMLによるSSOをFlaskアプリで実装してる方がいた。
https://thinkami.hatenablog.com/entry/2024/02/12/230830
https://developer.okta.com/code/python/pysaml2/
　IdP：Keycloak
　SP：Flaskアプリ
という構成。

https://www.keycloak.org/
KeycloakというのはID管理のためのオープンソースソフトウェアらしい。

上記のサイトに従ってコードを動かして、Keycloakの設定もしてみたが、
Keycloakの認証画面に飛ぶ際にInvalid Redirect Uriとなって認証画面に到達できなかった。
Keycloak側の設定の問題かもしれない。
Keycloak以外のIdPでのSAML認証も試してみたい。が、あんまり日本語のドキュメントがないのがつらみ。

Azure AD（現在はMicrosoft Entra ID）でSAMLを使ったSSOについては以下が参考になりそう。
https://learn.microsoft.com/ja-jp/entra/identity/enterprise-apps/add-application-portal-setup-sso
https://youtu.be/glZuiP8mjnA?si=_fUsK0PthI7fDYSe
Deviseでのユーザー情報更新時に関連データの誤更新を防ぐ方法

## 背景
RailsのDeviseライブラリを使用している際、Companyユーザーの情報を更新する際に関連データが誤って更新される問題が発生しました。特に、パスワードの検証が失敗しても、その他の関連モデルの変更（今回の場合はaccept_nested_attributes_forで関連付けられた `CompanyBusinessDay` や `CompanyBusinessHours`）が保存されてしまいます。

## 問題の原因
この問題の根本的な原因は、Deviseの更新処理（`update_with_password` メソッド）が単一のトランザクション内で実行されていないため、パスワードの検証に失敗しても他のデータベース変更がコミットされてしまうことにあります。

## 解決策
解決策として、Deviseの `update` アクションをオーバーライドし、全ての更新処理をカスタムトランザクションブロック内で実行します。これにより、すべての変更が正しいパスワードの検証を通過した後にのみコミットされるようになります。

## 実装方法
以下は、カスタムのトランザクションを用いた `update` アクションのサンプルコードです。

```ruby
# app/controllers/companies/registrations_controller.rb
class Companies::RegistrationsController < Devise::RegistrationsController
  def update
    self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)

    ActiveRecord::Base.transaction do
      if update_resource(resource, account_update_params)
        yield resource if block_given?
        if is_flashing_format?
          set_flash_message :notice, :updated
        end
        sign_in resource_name, resource, bypass: true
        respond_with resource, location: after_update_path_for(resource)
      else
        # 更新が失敗した場合、ロールバック
        raise ActiveRecord::Rollback
      end
    end
  end

  private

  def update_resource(resource, params)
    resource.update_with_password(params)
  end
end
```

#### 説明
- `update_resource`: Deviseの標準的なパスワードによる更新メソッドを呼び出しています。
- トランザクションブロック: `ActiveRecord::Base.transaction` を使用して、すべてのデータベース操作を一つのトランザクションとして管理します。これにより、何らかのステップで失敗した場合に全てのデータベース変更をロールバックすることができます。

この手法により、パスワードの検証が正しく行われ、関連データの安全な更新が保証されます。また、この方法はDeviseを使用している多くのRailsアプリケーションに適用可能です。
個人PCにTableau Desktop (Public Edition)を入れる方法(2024)

## はじめに

仕事上でTableauを使うようになったのですが「非業務のデータに対しても分析・可視化で使えそうだな…」と思い調べていたら、機能制限はありますが個人PCでもTableau Desktopが使えるとのことで、記事化しました。
~~仕事はどうでもよく~~、私生活で持ってるデータをどんどん可視化しましょう！

### Tableau Desktop (Public Edition)とは

Tableauの製品は色々あるのですが、今回入れるものはTableau DesktopのPublic専用版です。
ワークブックをローカルに保存できないのですが、Tableau Desktopの基本操作は可能です。

|製品名|価格|ブラウザ上で使うか|特徴|
|---|---|---|---|
|Tableau Desktop|<span style="color: red;">有料</span>|X|可視化ツール。PC上にソフトをインストールして操作。主に法人向け。|
|Tableau Prep|<span style="color: red;">有料</span>|X|データ操作ツール。PC上にソフトをインストールして操作。主に法人向け|
|Tableau Server / Tableau Cloud|<span style="color: red;">有料</span>|O|Tableauの機能をSaaSで実現。Desktopに若干機能が劣るところがある|
|Tableau Public|無料|O|「イケてる可視化を作って全世界に公開」するためのTableau Server。誰でも使える。ローカルにTableauワークブックファイルを保存できない（保存＝全世界公開）。主に個人向け|
|Tableau Desktop Public Edition|無料|X|Tableau Publicの「PCにインストールして使う」版。Tableau Dektopの方が若干高機能なので、色々試せる。|

## 入れ方

1. Tableau Publicのホームページに移動
https://public.tableau.com/app/discover

2. 左上の「作成」から「Tableau Desktop Public Editionのダウンロード」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789636/b4b1e641-b222-70ed-2f5e-8a9aa073e2fa.png)

3. 新しいタブが開くので「TALBLEAU PUBLICをダウンロード」をクリックする
4. 「姓」「名」「勤務先メールアドレス」「国／地域」を入力して「アプリケーションのダウンロードを押す」
勤務先メールアドレスは、仕事で使う可能性があるのなら勤務先、個人PJなら個人メアドで良い気がします（個人でTableauを契約する可能性がある場合・・・）
5. インストーラがダウンロードされるので、PCにインストール

### 作ってみた

ｺﾞﾆｮｺﾞﾆｮして作ったデータを可視化してみました。
タンパク質の多いメニューが一発で分かる！（古いメニューですが・・・）

https://public.tableau.com/app/profile/takaaki.murata/viz/_17124783213040/sheet1

## 最後に

Tableau Desktopの（ほぼ？）全機能が使えます。
Tableau Desktop Specialist試験の勉強でも大活躍！！
[自分用] 競プロのための累積和入門

5/11に開催されたABCコンテストにおいて、C問題が何度もTLEとなり解くことが出来なかった。
その対策として、「累積和」を取り入れる必要があると思ったので、学習しながらここに記していく。


### 参考にした記事
https://qiita.com/xryuseix/items/1059101a31107ba330d4

### 累積和とは

・・配列内の総和を求める処理を爆速にする手法


## 累積和の考え方

例えば、以下のような要件があったとする。

要件：以下の10個の自然数のうち、連続する3つの和の最大値を求めよ

1,8,4,2,5,6,3,7,1,4



### 手順1

配列Aに10個の自然数を格納。
配列A[1,8,4,2,5,6,3,7,1,4]

### 手順2

配列Bの0+N番目に、配列Aの0からN-1番目の和を格納。
配列B[0,1,9,13,15,20,26,29,36,37,41]

#


上記からわかることは以下。

配列Aのiからx番目までの和は、配列Bのx+1とiの差に一致する。
例えば、配列Aの1番目から3番目までの和を配列Bから求めるとする。

i=1,x=3のため、
配列Aは
配列A[1] + 配列A[2] + 配列A[3] = 8+4+2 = 14
配列Bは
配列B[4] - 配列B[1] = 15-1 = 14


このように、累積和を使えば、連続するn個の和を高速で算出することが出来る。

これを利用して最初の問題を解くと、「連続する3つの和」は配列B[n+3] - 配列B[n]に一致するため、連続する3つの和の最大値のみを常に保持しておけば、配列Bの末尾まで探索が完了した時に保持している最大値が配列Aにおける連続する3つの和の最大値ということになる。
この問題の場合、配列Bの36から20を引いた16が連続する3つの和の最大値となる。

配列B[0,1,9,13,15,20,26,29,36,37,41]


## 累積和をJavaで実装

具体的にJavaでプログラムを書いて問題を解いてみる。


```
public static void main(String[] args){

  int[] A = {1,8,4,2,5,6,3,7,1,4};

  int[] B = new int[A.length+1];

  B[0] = 0;

  for(int i=1;i<A.length+1;i++){
    B[i]= B[i-1] + A[i-1]; //配列Bに累積和を格納
  }

  int maxNum = 0;
  for(int i=0;i+3<A.length;i++){
    if(B[i+3]-B[i]>maxNum){
      maxNum = B[i+3]-B[i]; 
      //現状保持している連続する3つの和の最大値より大きかった場合、最大値を変更
    }
  }

  System.out.println(maxNum); //最大値を出力

}

```


コンソールには16が出力される。


# まとめ

累積和を使うことで、2重ループなどを行う必要がなく、処理が高速化する。競プロで勝ち抜くために必要な知識だと感じたので、記事にした。
今後も必要に応じて記事を更新していくので、Qiita、Twitterのフォロー推奨。
MyBatis Dynamic SQLの導入で、Java開発を楽にしたい！

# 資料の目的
MyBatis Dynamic SQLの導入により、SQL周りのJava開発を楽にしたい！

# MyBatis Dayamic SQLとは？
- SQL文をJavaの関数で書けるようにするMyBatisの機能です

- Java上でMyBatisのアノテーション＋SQLベタ書きで書かなくなります

- 通常のMyBatis同様、MavenやGradleでインストールできます

# 結論

**メリット**
- Javaの関数で、WHERE、ORDER BY、IN、LIKE、JOIN、AS、DISTINCT、MAXはもちろん、INSERT文、UPDATE文、DELETE文も書けます。if else文、CASE文、サブクエリ文、LIMIT OFFSET文も対応しています。SQL文はJavaの関数で表現できるため、Eclipse等のIDEによる文法チェック機能や一括修正機能の恩恵を受けられ、保守性に優れています
- MyBatis Generatorに対応しており、テーブルやカラムのマッピングは自動生成が可能です
- xmlファイルを作らずに済みます。並行して利用することもできます
- 公式のリリースが続いています

**デメリット**
- 書く文量が多いです。そのためコピペを多用せざるを得ません

# リンク集

公式サイトはこちらです。ドキュメントが充実しています。
https://mybatis.org/mybatis-dynamic-sql/docs/quickStart.html

公式GitHubはこちらです。テストソースに実際のMyBatis Dynamic SQLの文が大量に載っており便利です。
https://github.com/mybatis/mybatis-dynamic-sql

# 所感

主観になりますが、MyBatis Dynamic SQLはあまりにも便利すぎて、偉大な発明とさえ思ったりします。広まれ～広まれ～
Java以外の言語にも同様のツールがあればいいなと思います。
WordPressで検索結果から固定ページを除外する方法

WordPressで検索結果から固定ページを除外する方法について解説します。

## **functions.phpに記述するコード**

```php
function my_posts_search($search, $wp_query) {

	if ($wp_query->is_search() && $wp_query->is_main_query() && !is_admin()) {

		$search .= " AND post_type = 'post' ";

	}

	return $search;
}
add_filter('posts_search', 'my_posts_search', 10, 2);
```

## posts_searchフィルターフックについて

`posts_search`はWordPressの検索クエリのSQL WHERE句をカスタマイズするためのフィルターフックです。このフィルターを利用することで、デフォルトの検索機能を拡張し、特定の条件に基づいて検索結果を絞り込むことが可能になります。

`posts_search`フィルターフックは、2つの引数を受け取ります。これらの引数はフックの仕様に基づいて定めれており、以下の役割を持ちます。

1\. 第一引数`$search` （検索クエリの SQL WHERE 句）
- $searchは、WordPressが生成するデフォルトの検索クエリのSQL WHERE句を含む文字列です。これは、ユーザーがサイト内検索バーに入力したキーワードに基づいて自動生成されます。通常、この文字列は投稿のタイトルや内容にユーザーの検索キーワードが含まれるかどうかをチェックする条件が設定されています。
        
    ※この文字列に追加のSQL条件を組み込むことで、例えば特定のカテゴリやタグに属する投稿のみを検索結果に含めるといったカスタマイズが可能です。
        
<br>

2\. 第二引数`$wp_query` （WP_Queryオブジェクト）
- $wp_queryは、現在実行中のクエリ状況を管理するWP_Queryクラスのインスタンスです。このオブジェクトには、クエリがどのようなページ（例えば、フロントページ、アーカイブページなど）で実行されているか、またはクエリがメインクエリであるかサブクエリであるかといった情報が含まれています。
        
    ※このWP_Queryオブジェクトを利用して、クエリが実行される特定の条件に基づいてフィルタの適用を制限したり、特定の条件下でのみカスタマイズを行うように設定することが可能です。
        
    

## 関数の定義

```php
function my_posts_search($search, $wp_query) {
```

`posts_serch`フィルターフックの仕様に基づいて、第一引数に`$search`、第二引数に`$wp_query` を定義しています。

## 検索クエリの条件的なカスタマイズ

```php
if ($wp_query->is_search() && $wp_query->is_main_query() && !is_admin()) {
```

`$wp_query->is_search()`: ここでは、現在実行中のクエリが検索結果ページのクエリかどうかを確認します。つまり、ユーザーが検索バーに何かを入力して検索ボタンを押した結果に基づくページが表示されているかを判定します。

`$wp_query->is_main_query()`: ここでは、現在のクエリがメインのクエリであるかをチェックします。

`!is_admin()`: この条件は、現在のページがWordPressの管理画面ではないことを確認します。管理画面では検索クエリのカスタマイズが必要ないため、このチェックを行い、フロントエンドの検索機能にのみ影響を与えるようにしています。

これらの条件を組み合わせることで、フロントエンドのメイン検索クエリにのみ影響を与えるようにします。

## WordPressのデータベースクエリに条件を追加

```php
$search .= " AND post_type = 'post' ";
```

この行のコードは、PHPにおける文字列の連結を利用して、既存の`$search`変数に新たな条件を追加しています。

1\. `$search`変数：この変数には、`my_posts_search`関数が呼び出された時点でのWordPressのSQL WHERE句が含まれています。具体的には、ユーザーが検索フォームに入力してキーワードに基づいて自動的に生成されたSQL文が格納されています。

※例えば、ユーザーが検索ボックスに「apple」と入力した場合、WordPressは通常、以下のようなSQL WHERE句を自動生成します。

```sql
WHERE post_title LIKE '%apple%' OR post_content LIKE '%apple%'
```

2\. `.=` 演算子: これは「連結代入演算子」と呼ばれ、左側の変数（この場合は`$search`）に右側の文字列を追加（連結）します。この操作により、`$search`変数の既存の内容に新たな文字列が加わります。

3\. `" AND post_type = 'post' "`: この部分は、追加される新たな条件を表します。ANDはSQLにおいて複数の条件を組み合わせるために使用されるキーワードです。このように記述することで、検索結果を「投稿（post）」タイプのみに限定します。

## **add_filter 関数**

```php
add_filter('posts_search', 'my_posts_search', 10, 2);
```

`add_filter`はWordPressが提供する関数の一つで、特定のフィルターフックに対して、カスタム関数（コールバック関数）を登録します。（上記では、`posts_search`フィルターフックに`my_posts_search`関数を登録しています）この関数を使うことで、WordPressの標準的な動作に介入し、拡張や変更を加えることが可能になります。

### add_filterの基本的な構文内容

```php
add_filter( $tag, $function_to_add, $priority, $accepted_args );
```

- $tag : フィルターフックの名前です。これは、関数が結び付けられるフックを指定します。
- $function_to_add : フックに結びつける関数の名前です。この関数がフックが実行されたときに呼び出されます。
- $priority : 関数が実行される優先順位を指定します。数字が小さいほど先に実行されます。デフォルトは10。
- $accepted_args : 関数が受け取る引数の数です。デフォルトは1。

## 最後に
このように、`posts_search`フィルターフックを利用して、検索結果から固定ページを除外し、投稿タイプが「投稿（post）」のものだけを表示するようにカスタマイズします。
レコード記述子ワード（RDW）とは？

# はじめに
メインフレーム（汎用機）で稼働しているシステムをオープン系に移行（マイグレーション）する業務に従事することになった。
その中で得た知見を整理するために記事にすることにしました。
また、この現代に汎用機に関わる業務に従事することになってしまった方の役に少しでもなればと思います。
不定期になるかと思いますが、メインフレームマイグレーションで得られた知見を共有していきたいと思います。

***第一弾は、可変長データセットを扱う上で必須知識になるレコード記述子ワード（RDW）についてまとめてみました***

# レコード記述子ワード(RDW)とは
端的に言うと、データ内の各レコード（行）の長さが格納された領域です。
各行の先頭４バイトに格納されています。
最初の２バイトが各行のレコード長で、残りの２バイトがスパンドレコード用の予約領域です。
大抵、スパンドレコード用の予約領域は「0」つまり"0000"になります。
最初の２バイトに格納されるレコード長ですが、ここはRDW領域の４バイトも含むものになります。そして、レコード長は16進数の値が入ります。

私の経験では、メインフレーム上で可変長データを参照してもRDW領域は表示されません:sweat:
:warning:メーカによっては表示されるかもしれません。

例えば、以下のようなファイルがあった場合
```text:サンプルファイル
     ----+----+----+----+----
0001 abcdefghij
0002 1234567890abcdef
```
1行目は、10文字あるため純粋なレコード長は10バイトですが、RDWに格納されるレコード長は+4バイトした14バイトとなります。
そのため、RDWには「000e0000」となります。
2行目は、16文字あるため純粋なレコード長は16バイトですが、RDWに格納されるレコード長は+4バイトした20バイトとなります。
そのため、RDWには「00140000」となります。

# 最後に
メインフレームからオープ系にデータ移行する際の簡易なツールを作成してみた。
ファイルを読んで、指定したRDW情報を各行の先頭に付加して出力するシェルスクリプトです。

https://github.com/LittleBear-6w6/MainframeMigration/tree/main/AddRDW

# 参考情報

https://www.esector.co.jp/ops/mainframe/ec-003.html

https://www.microfocus.co.jp/manuals/ED22/html/HRCDRHCDIR95.html

https://www.hulft.com/help/ja-jp/HULFT-V8/XSP-ADM/Content/HULFT_ADM_MF/Env/Variable_file_RDW.htm