OmniAICreator/Qiita-1.07M huggingface dataset:
s4hanaのスペース及びページの作り方

# やりたいこと
s4hanaのホーム画面上に、スペースとその下にあるページを作成する

# やり方

## 一、スペースとページの作成

### ①ホーム画面にて、「space」を検索
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/58f54ebb-85ef-0df9-04e6-572476a4cd00.png)

### ②「Managed Launchpad Spaces」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/85b73d2e-71c5-7cbe-a6e3-3591837f52c3.png)

### ③「create」をクリック
以前作成したスペースの一覧はこの画面に表示される。
以前のものを編集したい場合はスペース名を、新規で作りたい場合は「create」をクリックする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/774c65aa-fe21-2ac6-4512-8a560ac15ba4.png)

### ④スペースとページ情報を入れ、「create」をクリック
IDやスペース名を入力する。
そのスペースの下にぶら下がっている「ページ」もこのタイミングで一緒に作れるので、IDとページ名を入力する。
※IDは「Z」で始まり必要があるらしい。。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/64a96f1e-b9a1-0a97-9620-d61726376d6e.png)

### ⑤次の画面で、「save」をクリック
前画面で入力した情報を確認し、saveをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/6ef19fd2-4510-64d9-e598-fcf445227d1d.png)

これでいったんスペースとその配下のページが作成できたが、権限を付与しない限り誰もこのスペースを使えない状態。。。

## 二、ロールでスペースを見る権限を付与

### ①ホームに戻り、「role」と検索
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/6bae70fb-79eb-e44b-a5b2-c3608d43d0a3.png)

### ②「Maintain Business Roles」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/b3cb9e53-8212-241f-d3c4-46bd96aa5ac6.png)


### ③アサインしたいロールにチェックを入れ、「mass change」をクリック
※事前にロールを作成し権限を設定済み
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/c922a226-6afb-b5e2-eedd-559c3c0f1ad2.png)

### ④「Launchpad Space Asignment」を選択、「Next Step」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/b6949792-acf0-41c3-58be-e171697374ec.png)


### ⑤「Add Launchpad Space」を選択し、「Next Step」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/282e8530-11d0-0261-97bc-da33770a1059.png)

### ⑥このアイコンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/feb8b3de-4fef-9ba7-b4d0-628e42864023.png)

### ⑦作ったスペースにチェックを入れ、「OK」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/5aa3007b-4921-1b39-0ba1-bfe84b615080.png)


### ⑧「review」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/72bc51ee-2497-802c-aff5-5fd9ef2029d9.png)

### ⑨「Submit」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/3b0906bf-11d7-7c57-2d8c-61c887bcca18.png)


### ⑩「close」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/6cff18d3-f083-747f-9aa3-aa42084310d4.png)

### ⑪HOMEに戻ると、テストスペースのタブが出て、ページもできた！
このロールを持っている人は全員スペースを見れるはず
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/7c638ff6-ccf5-2e90-6139-f377e490ff96.png)


# 終わりに
s4hanaの公式ドキュメントはいろんな情報が混ざっていて、しかもシステムのバージョンアップとかにより結構古い情報も入ったりしますので、有用な情報を探すのに時間がかかった。。。

今回は自分なりに模索しながら、ようやくスペースを作成できたのでブログとして手順を残したいと思います
DMARC導入してみた

## **▽概要**

Googleや米Yahoo！が2024年2月(Yahoo!は第一四半期だったかな)メールガイドライン改定で、

>Google(個人用)とYahoo！それぞれ1日5000件以上メールを送っているなら、
>SPF,DKIM,DMARCを設定し、強力なメール認証を導入しないとメール届かなくなる可能性がある

ということで、DMARC導入を検討しました。


 https://support.google.com/a/answer/81126?hl=ja&visit_id=638410862513529055-2117125000&rd=1#zippy=%2C%E3%81%99%E3%81%B9%E3%81%A6%E3%81%AE%E9%80%81%E4%BF%A1%E8%80%85%E3%81%AE%E8%A6%81%E4%BB%B6

「なにから良いのか…」と悩まれているかたへのお力になればと思い、DMARC導入でやったことをまとめました。


## **▽簡単なDMARCの説明**
SPFやDKIMの判定で認証失敗したメールを受信側でどういう処理させるか定義する仕組みのこと。
1つのドメインに対して1レコード設定できる。

※とても分かりやすくまとめられているIIJ様のページを紹介します。
　(決してIIJ様のあれではございませんが、このページが個人的にはとても分かりやすいです)

https://ent.iij.ad.jp/articles/172/

<br>

## **▽大まかな流れ**

①DMARC設定値検討
②DNSサーバにDMARCレコード設定
③動作確認

DKIM導入時よりやることが少なくて…ありがてええええ


<br>

## **▽各工程でやったこと**
<br>

#### ①DMARC設定値検討

DMARCはドメインに対して1つ設定ができるとのことで、設定値を考えてみました。

```
設定例
_dmarc.●●.jp
タイプ：TXT
v=DMARC1; p=none;rua=mailto:hoge@●●.jp;ruf=mailto:hoge@●●.jp;sp=none;
TTL：3600

```
まずは基本的な内容の↓このオプションを設定しました。
(これ以外にもいろいろなオプションがありますが、今後検討してみます…)
|オプション名|詳細|設定値|
|:--|--|--|
|v(必須)|DMARCのバージョン|今のところ”DMARC1”でOK|
|p (必須)|ポリシー|none(何もしない、モニタリング)<br>quarantine(隔離、受信者の迷惑メールに入れる)<br>reject(拒否、受信者にメールを受信させない)
|rua(オプション)|集計レポート送信先|メールアドレスを指定する
|ruf(オプション)|認証チェックに失敗した時のレポート送信先|メールアドレスを指定する
|sp(オプション)|サブドメインの定義|none(何もしない、モニタリング)<br>quarantine(隔離、受信者の迷惑メールに入れる)<br>reject(拒否、受信者にメールを受信させない)<br>※親ドメインと同じ動きにしたい場合は省略OK

"p"について、まずはnoneで様子見て、大丈夫そうならquarantineやrejectを検討しようかと思い、
とりあえずp=noneで設定しました

:::note info
”v”と”p”だけ必須ですが、”rua”は設定しておくことをオススメします
ruaを設定しておくことで、メール送信先のメールサーバから1日1回「あなたは私のメールサーバへこんなメールを送ってきましたよ」っていう、1通1通のメールに対してのSPFやDKIMの認証状況などが記載されたレポートが受け取れます
:::

<br>

#### ②DNSサーバにDMARCレコード設定

①で決めた値を設定する。
DMARCはTXTタイプで設定すればOK👍
DNSの設定方法はレジストラによって手順が異なるので、以下参考↓
[お名前.comのネームサーバを使用している場合のTXTレコード設定方法](https://www.onamae.com/guide/p/70?_gl=1*5urqv8*_gcl_au*MTkyNzA2OTYwNC4xNzA2NjgxMjg4&_ga=2.268414926.1761652878.1706681288-1434159120.1706681288)


<br>

#### ③動作確認
下記のコマンドプロンプトから確認したり、[CMANインターネットサービス](https://www.cman.jp/network/support/nslookup.html)からDMARCレコードが設定されていることを確認しました。

ちなみに、ruaを設定した場合、設定後の翌日くらいから、DMARCレポートが届き始めます。

```
C:\User\●●>nslookup
>server 8.8.8.8 (GooglePublicDNS以外のなんでも良いのでサーバを指定)
>set type=TXT 
>_dmarc.●●.jp (調べたいドメインを指定)
```

## **▽最後に…**
DMARCって他の国に比べて、日本の企業の導入は少数らしいです。
今回のGoogleや米Yahoo！のメールガイドライン改定で、本腰を入れ調べ始めました。

今後ポリシーをquarantineやrejectに検討し、より強度なメール認証にできたら良いなと思います。
try Autify UI test automation

# Background

Autifyが現在のテスト自動化より効率的かを検証してみた。

# proxy (private) のテスト環境

自分のテスト環境は、社内に限られ、proxyで接続してのみ利用可能である。
Autifyはテスト実行はAutifyのcloud環境で行われる。
Helpにある通り、実行環境と連携してテスト実施は可能ではあるが、ハードルが高い。

https://help.autify.com/docs/ja/primer-for-private-testing

# senario edit

編集したいステップまでテストを進めることは可能。
だが、手動で1 step毎に進めることができないのが不便

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/25fabb6e-fa94-777a-27e6-7a419a324224.png)


ほしい機能
- 一時的に一部STEPを無効にする（SKIP)機能。削除しかないので、戻したいとき再編集が必要
- if 文でSTEPを分岐・条件を満たすときのみSTEP・ステップグループの追加する機能
- 一部のSTEP・ステップグループをデータ駆動でループする機能。シナリオ全体のループは可能だが。


# データ駆動

シナリオ単位でデータ駆動が可能

まず、データ駆動するためのデータソースをuploadする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/e0678cb0-16f6-df21-94f6-d0016dbe0bcb.png)

次にシナリオの値を入力するSTEPで、先ほどのデータの変数名に変更する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/7704532e-856a-ee08-9e7e-3c81847368f8.png)

楽にデータ駆動の設定ができた。Ranorexと同様なやりかた。
Mablはjsスニペットで実現するので、Autifyは易しい。


# 要素の特定

capture & reply型なので、操作したときの要素を毎回選択し、クリック等が行われる。

今回、楽天競馬で　”ある競馬場の11Rの投票をクリックする”　ステップを考える。
なお、この投票リンクの表は毎日変わる（対象の競馬場が異なる。レース数が異なる。（最大12レース））

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/2a7c9fa1-aaae-98bf-f1ab-79b44e521053.png)

作成後、シナリオを確認した時が、以下のとおりである。
先ほどのように、表の中に数多くの”投票リンク”があるなかで、クリックする場所がどういった基準で選ばれているのかが不明である。

- 姫路の11R
- ３番目の競馬場の11R
- 姫路でクリック可能な投票リンク６番目

という風に、いろいろな解釈ができる。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/2b203ddf-2519-3796-47eb-321ce53714ec.png)


実際に、毎日実施してみると、クリックする競馬場は異なっている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/3142d5f5-3489-d1f7-d2c9-c44928264d61.png)


そこで、locatorを明示することで、その不明確さをなくすこともできる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/874c9a5b-14d8-571d-644f-f3f2366eb5ce.png)

なお、xpathを取得する方法はhelpに記載されている
ただ、今回のようにテーブルの特定の行・列を指定するとき単純にdeveloper toolでは取得できなかった。コツがいる。


https://help.autify.com/docs/ja/how-to-get-css-selectors






# reporting (failur)

テストを失敗したときのレポートの例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/69650cbe-e75d-ec79-1fbb-8c6e5743005c.png)

- 各ステップの処理時間が明確
- どのステップで失敗し、原因が明確
- 動画で確認可能
- 失敗したステップから編集可能
Pythonを使ってAzure DevOpsからPull Requestを取得する

## やりたいこと
Azure DevOpsのReposからPull Requestを引っこ抜きます。Pull Requestの情報から、プロジェクトがどの程度コードを生産しているか、どの程度レビューに時間を割いているか計測したいのです。普通に開発する分には気にすることは無いと思うのですが。

## 環境
Python 3.9.2
Azure DevOps api version 7.1

azure-devopsを使います。pipからインストールしてください。

## コード
```Python
from azure.devops.connection import Connection
from azure.devops.v7_1.git.models import GitPullRequestSearchCriteria
from msrest.authentication import BasicAuthentication

# Fill in with your personal access token and org URL
# repository_id is not repository name
personal_access_token = 'xxxx'
organization_url = "https://dev.azure.com/FUGAFUGA"
project_name = "ほげほげプロジェクト"
repository_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx"

# Create a connection to the org
credentials = BasicAuthentication('', personal_access_token)
connection = Connection(base_url=organization_url, creds=credentials)

# Get a client (the "core" client provides access to projects, teams, etc)
git_client = connection.clients_v7_1.get_git_client()

# search criteria
search_criteria=GitPullRequestSearchCriteria()
search_criteria.status="Completed"

pullrequests=git_client.get_pull_requests(repository_id,search_criteria)

for pr in pullrequests:
    print(str(pr.title)+":"+str(pr.created_by.display_name)+":"+str(pr.creation_date)+":"+str(pr.closed_date))

```

### PATの設定
personal access tokenはお手元のAzure DevOpsから取得してください。ネットに大量に情報があると思います。Scopesはおそらく以下が必要です。

- Code
Pull Requestを読み取るために必要。Read以上の権限を付与してください。
- Pull Request Threads
Pull Requestの中のやり取りを読み取るために必要。Read & write権限を付与してください。writeは必要ではないのですがread & writeが最小権限のようでした。
- Service Connections
APIアクセスするために必要っぽいです。

### 認証
この辺りはMicrosft LearnにあるPythonのサンプルコードの通りです。
PATにはPersonal Settingsから取得したトークンを指定してください。organization_urlはブラウザのアドレスバーを見ればわかると思います。repository_idはIDです、リポジトリ名とは異なります。ネットを検索すれば情報はあると思いますがProject settingsにあるReposから確認することが可能です。

## メソッドを実行する場合の注意
APIのメソッドはMicrosoft Learnに詳しい説明があります。Pythonの記法に則ってはいないことに注意してください。pull requestを全権取得するメソッドの説明はGetPullRequests()として記載があります。スネークケースへ読み替えてください。
Cursor エディタ (VsCode + ChatGPT)  でコード生成/編集する基本的な使い方

# コードを新しく生成する

ファイルの好きな行で好きなように指示するだけ

生成内容が気に入った場合はAccept(承認)する

<img width="832" alt="image" src="https://github.com/YumaInaura/YumaInaura/assets/13635059/3c39cb06-ce6b-4fb4-96cd-7dd73822a7f8">



# コードの編集

コードで編集したい部分を選択するとウィンドウが表示されるので、Editを選んで指示するだけ


![image](https://github.com/YumaInaura/YumaInaura/assets/13635059/d0fe22d3-c9a6-441f-889e-2bc70ef5e4a5)
!

同じく編集内容がOKならAcceptする

[image](https://github.com/YumaInaura/YumaInaura/assets/13635059/3b9becf2-b0c8-4d72-a5c9-199117bbed6b)

<img width="797" alt="image" src="https://github.com/YumaInaura/YumaInaura/assets/13635059/0a790406-cfcf-4c82-98fc-0a96f1feed91">



# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
クラウド選択、AWS、Azure、GCP、OCIどれが良いのか論争は不毛

## いちばん良いサービスを導入したいと思うのは当然だけれども
自動車選ぶ時に、トヨタ、日産、ホンダ、マツダ、三菱、スズキ、スバル、ダイハツ、どれが良いの？と考えるのと一緒。自分が購入するのが、スポーツカーなのか、コンパクトカーなのか、SUVなのか、ミニバンなのか、軽自動車（も更に分類されるますが）なのかによって、どのメーカーが良いのか良し悪しがあります。
## 利用するサービスによって良し悪しは変わってくる
自動車でいえば、たとえば、ミニバンはトヨタだけれども、スポーツカーなら日産というように用途によって良し悪しかわってきますし、軽自動車がほしいのに、基本軽自動車を販売していないトヨタが良いというのも妙です（最近は、トヨタにもダイハツOEMの軽自動車がラインアップされていますが）。
## とはいえ複数サービスの利用が一般的なクラウドの選択は複雑
一般家庭の場合、自動車の選択は単一になるケースが多いですから比較は楽です。クラウドの場合、単一サービスのみを利用するわけではないので、自動車メーカー選択の様に簡単にはいきません。
## 利用する主サービスを考慮する
こんにちの大手のクラウドベンダーのほとんどサービスは、誤解を恐れずにいえば、大きな違いはありません。そこで考慮すべきには、どのサービスにプライオリティを置くのか？という点です。例えば、仮想マシンが重要ならA社、LLMが重要ならB社の様に考えます。
## 複数のクラウドを利用する場合の注意点
自動車の場合は、複数のメーカーの自動車を所有しても大きなデメリットはありません。家族用にトヨタのミニバン、街乗り用にスズキの軽自動車、なんて組み合わせもありうるでしょう。しかし、クラウドはそう簡単にはいかないのは容易に想像できること。仮想マシンはA社、LLMはB社のような組み合わせで利用する場合、単一のクラウドベンダーを利用している場合と比較するとデメリットがあります。そのデメリットと組み合わせた時のメリットを考慮して、複数のクラウドベンダーを利用するかどうか判断します。
## 比較する際にはベンダー全般で比較しない
言い換えれば、ベンダーが提供しているすべてのサービスを比較して良し悪しをつけないこと、利用するサービスで比較するのが重要です。
動かして試す、git resetの動き

## 環境
Ubuntu 20.4
Git 2.25

## はじめに
git resetの３つのオプションの違いについて書いてみました。
- --soft
- --mixed
- --hard


##### --mixed
ステージングエリアだけをクリアし、ワーキングディレクトリはクリアしません。git addした後、「このまま、commitしないで、やっぱり取り止めよう」となった場合に使います。

##### --hard
ワーキングディレクトリが、過去のコミット履歴の状態に戻ります。ステージングエリアに上がっているファイルがあればクリアされます。

##### --soft
コミットの取り消しだけが行なわれます。ステージングエリアとワーキングディレクトリの内容は、クリアされず現状のまま残ります。

## --mixedの動き
test1.txtとtest2.txtの２つのファイルを修正した後、ステージングエリアに上げます。
```
$git add .
$git status
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   test1.txt
        new file:   test2.txt
```

２つファイル共、ステージングエリアから降ろされました。ステージングエリアから降りても、ワーキングディレクトリがクリアされることはありません。現状のワーキングディレクトリの内容でそのまま残ります。
```
$git reset --mixed
$git status
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        test1.txt
        test2.txt
```

複数のファイルがステージングエリアに上がっている場合、ファイルを指定してステージングエリアから降ろすことができます。test1.txtとtest2.txtがステージングエリアに上がっていて、test1.txtだけを、ステージングエリアから降ろしました。test2.txtだけが、ステージングエリアに残っている状態です。
```
$git add .
$git reset test1.txt
$git status
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   test2.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        test1.txt
```

test2.txtもステージングエリアから降ろすと、ステージングエリアに上がっているファイルはゼロになりました。
```
$git reset test2.txt
$git status
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        test1.txt
        test2.txt
```

次の２つのコマンドの動きは同じです。--mixedは省略することができます。
```
$git reset
$git reset --mixed
```

次の３つのコマンドの動きはすべて同じです。
```
$git reset
$git reset .
$git reset ./
```

## --hardの動き
コミットをした後、ファイルを修正して、次のコマンドを実行すると、直前にコミットをした状態に戻ります。つまり、ワーキングディレクトリの内容がクリアされます。git addでステージングエリアに上げている状態であれば、ステージングエリアの内容もクリアされます。
```
$git add .
$git reset --hard
$git status
nothing to commit, working tree clean
```

HEADより一つ下の履歴に戻す場合です。下記の２つのコマンドは同じです。HEAD^の代わりに、履歴IDを指定して、複数の履歴を横断して、過去の履歴に戻すことができます。
```
$git reset --hard HEAD^
$git reset --hard 4c0a5a0
```

HEADは省略して書くことができます。つぎの２つのコマンドは同じです。
```
$git reset --hard
$git reset --hard HEAD
```

コミットされたファイルが複数存在する場合、特定のファイルを指定して、コミットを取り消すといったことはできません。次のコマンドは全てエラーになります。test1.txtとtest2.txtの２つのファイルがコミットされている状態で、test1.txtだけを復活させて、test2.txtはコミットされた状態のままにしておくといったことはできません。
```
$git reset --hard .           # エラー
$git reset --hard ./          # エラー
$git reset --hard test1.txt   # エラー
```

## --softの動き
test1.txt、test2.txtの２つのファイルを修正して、ステージングエリアにあげます。
```
$git add .
$git status
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   test1.txt
        modified:   test2.txt
```

次のコマンドで、HEADよりも１個前の履歴を復活させました。しかし、ワーキングディレクトリが復元されることはありません。現状のワーキングディレクトリの内容のままです。ステージングエリアに上がっている２つのファイルも、引き続き、ステージングエリアに上がっている状態のままです。
```
$git set --soft HEAD^
$git status
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   test1.txt
        modified:   test2.txt
```

履歴IDを直接指定して、復元させることもできます。
```
$git reset --soft HEAD^
$git reset --soft caddd1
```

HEADよりも３個過去の履歴に戻す場合です。２つのコマンドはどちらも同じです。
```
$git reset --soft HEAD^^^
$git reset --soft HEAD~3
```
日本語パッケージ版EC2をデプロイする

今回は最初から日本語版のEC2(Windows Server2022)を構築する手順について記事にします。
ググると「EC2の日本語化」=「デプロイした後に日本語する」手順はたくさん記事があるのですが最初から日本語版のEC2をデプロイする記事はあまりなかったので書いてみました。


# 今回のゴール
最初から言語パッケージが日本語選択になっているEC2(WindowsServer2022)をデプロイする
![スライド1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/84dfb427-fea2-7d84-be1f-d78f757f2f28.png)


## 注意点
SQLライセンス付きのEC2もあるので間違えないようにしましょう。SQLライセンス付きにするとOSのみのAMIと比べて結構料金が***高い***です...

ちなみに価格を比較するとこんな感じです。※t3a系で比較

【WindowsのみのAMI】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/4ff1fecd-8928-1eed-53b6-5adb31af29a7.png)

【Windows+SQL(Web)のAMI】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/c8cdc1e4-2447-18e2-6414-a0cdb54ccb38.png)


# 実際の手順
①EC2 のダッシュボードで「インスタンスを起動」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/7edcc725-a942-70ba-9dac-ecb0024dd70f.png)


②Application and OS Imagesで「クイックスタート」-「その他のAMIを閲覧する」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/64575fb5-0c4f-758b-1d11-eca2a2fa5ee0.png)


③コミュニティ AMIのタブを選択し、検索欄(Select AMI)の画面に「Japanese」を入力し、検索
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655033/96776ea5-a9d8-c3cd-8a45-1a72139a423a.png)



④「Windows_Server-2022-Japanese-Full-Base-XXXXXXX」となっているAMIを選択する。
XXXXXXの部分は年月日付が入ります。
**<font color="red">間違って「Windows_Server-2022-Japanese-Full-SQL_2022」など"SQL"付きを選択するとエラい金額を請求されますのでご注意を！**</front>



# おわりに
ちょっとしたことでも調べると意外に時間がかかるので、初学者の方々の時短になれば幸いです。
Go言語でマイグレーションしたらエラーが出た

実行環境：mac

モデル、マイグレートファイルを作成後「GO_ENV=dev go run migrate/migrate.go」のコマンド実行でエラーが出ました。

`watashinomac-Pro-go-study % GO_ENV=dev go run migrate/migrate.go
gorm.io/driver/postgres
../go/pkg/mod/gorm.io/driver/postgres@v1.5.5/migrator.go:411:26: m.GuessConstraintInterfaceAndTable undefined (type Migrator has no field or method GuessConstraintInterfaceAndTable)`

調べたところ、driver/postgres@v1.5.5のドライバーのバージョンを下げればいいとのこと。

go.modの
	`gorm.io/driver/postgres v1.5.5`→	`gorm.io/driver/postgres v1.5.4`
 と修正し再度実行したところマイグレートができました！

参考
[【Golang】人のビルドプロセス見て我が振り直せ](https://zenn.dev/soramarjr/articles/fe0e9ac8891c32)
CLIでsplunkコマンド実行時の時刻がわかるようにする(小ネタ)


splunkコマンドの実行エビデンスを残す必要がある時や、splunk自身の調査をする状況において(splunkを)何時停止したっけ？とかを確認したい時に、
以下の内容を.bashrcや.zshrcに仕込んでおくだけで少し幸せになれます。

``` sh:.bashrcとか.zshrc
function splunk(){
    date;/opt/splunk/bin/splunk $@ ;date
}
```

``` :実行例
$ splunk restart
2024年 1月 １７日 水曜日 11時52分47秒 JST ← コマンド実行直前の時間が出るようになる
Stopping splunkd...
Shutting down.  Please wait, as this may take a few minutes.
.....
Stopping splunk helpers...

Done.

(中略)

Waiting for web server at http://127.0.0.1:8000 to be available..................................... Done


If you get stuck, we're here to help.
Look for answers here: http://docs.splunk.com

The Splunk web interface is at http://C02DH0Y8ML7J:8000

2024年 1月 17日 水曜日 11時53分53秒 JST ← コマンド完了直後の時間が出るようになる
$
```
EC2（WindowsServer）初回接続について

# 概要
EC2（WindowsServer）を新規作成後、そのサーバにログインする方法

## 前提
EC2（WindowsServer）が作成済みであること。

# 目次
- リモートデスクトップ接続をする場合
- SSM セッションマネージャ接続する場合

# リモートデスクトップ接続をする場合

## Windowsログイン用情報取得
1．AWSマネジメントコンソールにログイン → [EC2]コンソール画面表示する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/11a2538a-c805-3826-1f0d-c00552a20024.png)

2．作成したサーバ名の左の☑を入れて、[アクション▼] → [セキュリティ▶] 
→[Windowsパスワードを取得]を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/1f4b5222-4da0-a388-2674-04662555e2ad.png)

3．[プライベートキーファイルのアップロード]をクリックし、作成したサーバの秘密鍵（プライベートキー）を選択 → [開く] → [パスワードを復号化]をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/ed9e078c-1f22-e360-76de-496fd069a279.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/f31deb0e-401d-33ec-f793-c3089c879654.png)


4．[Username]と[パスワード]に記載されている情報を、任意のテキストにコピーして保存 → [OK]をクリックする。
## リモートデスクトップ接続
5．ローカルで[Windowsキー]＋[R]を押して、[ファイル名を指定して実行]で[mstsc]と入力 → [OK]をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/33d9776a-42e4-6101-61d8-726a113f89c8.png)

6．[コンピューター(C):]：[作成したサーバのパブリックIPアドレス]を入力 → [接続]をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/d38743ea-1790-1650-d71a-be16875d330c.png)

7．[ユーザ名]と[パスワード]に、手順4で任意のテキストに保存した情報をコピーして入力 → [OK] → [はい]をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/c0c64cb8-bdb0-d104-31a9-4a6f2a78f2a9.png)



# SSM セッションマネージャ接続する場合

## SSM QuickStart作成
1．AWSマネジメントコンソールにログイン → [EC2]コンソール画面表示する。
2．作成したサーバ名の左の☑を入れて、[接続]をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/59fc35c9-1e3c-1d87-d0a0-2d77838ea41d.png)

3．[セッションマネージャー]タブを選択し、[Quickstart]を選択する。
4．デフォルトのまま、[作成]をクリックする。
5．作成したサーバのIAMロールにSSMのロールがアタッチされていることを確認する。

## サーバにログインし、SSM Agent再起動
1．作成したサーバにリモートデスクトップ接続をする。
2．[Ctrl]＋[Shift]＋[Esc]を同時に押して、タスクマネージャを開く
3．[Service]タブを選択し、[AmazonSSMAgent]を右クリックし、[Restart]を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/101c43fe-0af4-6224-5e6c-0074d13e9f7a.png)

4．[EC2]コンソール画面表示する。
5．作成したサーバ名の左の☑を入れて、[接続]をクリックする。
6．[セッションマネージャー]タブを選択し、[接続]をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/fad18cf2-f362-8781-5648-05cccf5e69a2.png)
【08】Next.js app routerのチュートリアルやってみる(静的レンダリングと動的レンダリング)

# はじめに

Next.js app routerのチュートリアルの第８章のアウトプットします。

https://nextjs.org/learn/dashboard-app/static-and-dynamic-rendering

<details><summary>前の記事</summary>

【01】Next.js app routerのチュートリアルやってみる

https://qiita.com/naoyuki2/items/af58da3d20cbc790e767

【02】Next.js app routerのチュートリアルやってみる

https://qiita.com/naoyuki2/items/edf450b3ee135e83d1e8

【03】Next.js app routerのチュートリアルやってみる
https://qiita.com/naoyuki2/items/612221eac233aa9cbb74

【04】Next.js app routerのチュートリアルやってみる

https://qiita.com/naoyuki2/items/62f9beccbfe36eaf7f90

【05】Next.js app routerのチュートリアルやってみる

https://qiita.com/naoyuki2/items/8b71b1d1df7c9435a9c9

【06】Next.js app routerのチュートリアルやってみる

https://qiita.com/naoyuki2/items/58130c3cfbaf8a573de2

【07】Next.js app routerのチュートリアルやってみる

https://qiita.com/naoyuki2/items/2c2da0f8071e60454679

</details>

# 第８章 静的レンダリングと動的レンダリング

この章では下記を学習しました。

- 静的レンダリングとは
- 動的レンダリングとは

# 静的レンダリング

> 静的レンダリングでは、データのフェッチとレンダリングがビルド時 (デプロイ時) または再検証中にサーバー上で行われます。結果はコンテンツ配信ネットワーク (CDN)に配布およびキャッシュできます。

> ユーザーがアプリケーションにアクセスするたびに、キャッシュされた結果が提供されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582046/f15824c7-719d-89e3-091b-09cee2de4b9c.png)



`静的レンダリング`の利点としては、

- Webサイトの高速化 - 事前にレンダリングされたコンテンツをキャッシュしているため。ユーザーがアクセスしたときのリクエストが高速になります。
- サーバー負荷の軽減 - コンテンツがキャッシュされているため、サーバーはユーザーのリクエストごとにコンテンツを動的に生成する必要がありません。
- SEO - 事前にレンダリングされたコンテンツは、検索エンジンのクローラーに認識されるため、検索結果のらんキングが向上する可能性があります。

データのないUI、静的なブログ投稿や製品ページなど、`ユーザー間で共有されるデータ`を表示する際に役立ちます。

ですが、リアルタイムな情報を提供するダッシュボードなどには適さない可能性があります。

# 動的レンダリング

> 動的レンダリングでは、リクエスト時(ユーザーがページにアクセスしたとき)に、各ユーザーのコンテンツがサーバー上でレンダリングされます。

- リアルタイムデータ - リアルタイムまたは、頻繁に更新されるデータを表示できます。
- ユーザー固有のコンテンツ - ダッシュボードやユーザープロフィールなどのユーザー情報によってページを更新することが簡単になります。
- リクエスト時の情報 - `Cookie`や`URL検索パラメータ`など、リクエスト時のみ知ることができる情報にアクセスできる。

以下のコードでは、`next/cach`から`unstable_noStore`を`import`し、`noStore`として使用しています。

これにより、サーバーはキャッシュを返さず、動的レンダリングを実装できます。

```diff_tsx:/app/lib/data.ts
// ...
import { unstable_noStore as noStore } from 'next/cache';
 
export async function fetchRevenue() {
  // Add noStore() here to prevent the response from being cached.
  // This is equivalent to in fetch(..., {cache: 'no-store'}).
+ noStore();
 
  // ...
}
```

:::note alert
`unstable_noStore `は`unstable(不安定)`と書いてあるように、実験的なAPIであり、将来変更される可能性があるそうです。

安定したAPIを使用したい場合は下記を参照してください。
https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config
:::

これにより、動的レンダリングを実装できたのですが、

動的レンダリングを使用すると、`アプリケーションは最も遅いデータフェッチ`と同じ速度でしか動作しません。

そのため、読み込みなおすたびにページ全体がロックされてしまいます。

# おわりに

次回からその解決方法を見てみましょう。

# 次の記事

https://qiita.com/naoyuki2/items/717694288ec6017a3af2
RESTful APIメモ

## メソッドの種類

### 概要

| メソッド | 概要説明 |
|--------|--------|
| `GET`    | リソースの取得 |
| `POST`   | リソースの作成 |
| `PUT`    | リソースの更新/置換 |
| `DELETE` | リソースの削除 |
| `PATCH`  | リソースの部分的変更 |
| `HEAD`   | ヘッダー情報の取得 |
| `OPTIONS`| サポートするHTTPメソッドの取得 |
| `CONNECT`| プロキシ経由のトンネリング |
| `TRACE`  | リクエストの追跡 |

### 詳細

- **GET**
  - リソースを取得するために使用され、サーバーの状態を変更しない。ウェブページや画像などの読み込みに使われる。
- **POST**
  - 新しいリソースを作成するために使用される。フォームの送信や、サーバーにデータを送る操作に使われる。
- **PUT**
  - 既存のリソースを更新するか、指定されたURIにリソースが存在しない場合は新たに作成する。全体を置き換えることが特徴。
- **DELETE**
  - 指定されたリソースをサーバーから削除する。削除が成功したか否かはサーバーの実装に依存する。
- **PATCH**
  - リソースの一部を更新する。PUTとは異なり、リソースの全体ではなく一部分だけを変更する場合に使用される。
- **HEAD**
  - GETメソッドと同様だが、レスポンスボディを持たず、HTTPヘッダー情報のみを取得する。リソースのメタデータを確認する際に使用される。
- **OPTIONS**
  - サーバーがサポートするHTTPメソッドを確認するために使用。CORSの事前フライトリクエストで使用されることもある。
- **CONNECT**
  - ネットワークセキュリティが施された環境内でクライアントとサーバー間のトンネルを確立するために使用される。
- **TRACE**
  - クライアントからサーバーへのリクエストが中継される過程での変更を追跡するために使用。デバッグ目的で利用される。

## エンドポイントの設計

### 基本原則

1. **明確な命名規則**:
   - エンドポイントは、対象となるリソースを明確に示すべきです。複数形を使用してリソースのコレクションを示し、単数形を使用して個々のリソースを指します。

2. **階層的な構造**:
   - リソース間の関係を表現するために階層的なURL構造を使用します。これは、リソース間の親子関係を直感的に理解させるのに役立ちます。

3. **CRUD操作の使用**:
   - エンドポイントは、CRUD（作成(Create)、読み出し(Read)、更新(Update)、削除(Delete)）操作をサポートするように設計されるべきです。HTTPメソッド（POST、GET、PUT/PATCH、DELETE）をこれらの操作にマッピングします。

4. **状態レス**:
   - 各リクエストは独立しており、クライアントの状態をサーバーに保存しないようにします。これは、スケーラビリティと再利用性を向上させます。

5. **フィルタリング、ソート、ページネーション**:
   - データの取得方法を柔軟にするために、クエリパラメータを使用してフィルタリング、ソート、ページネーションをサポートします。

### 設計例

- **リソースのリストを取得**:
  - `GET /users` : 全てのユーザーのリストを取得します。
  
- **単一のリソースを取得**:
  - `GET /users/{id}` : 特定のIDを持つユーザーの詳細を取得します。
  
- **新しいリソースを作成**:
  - `POST /users` : 新しいユーザーを作成します。リクエストボディにユーザー情報を含めます。
  
- **リソースを更新**:
  - `PUT /users/{id}` : 特定のIDを持つユーザーの情報を更新します。全ての情報をリクエストボディに含めます。
  - `PATCH /users/{id}` : リソースの一部を更新します。変更される情報のみをリクエストボディに含めます。
  
- **リソースを削除**:
  - `DELETE /users/{id}` : 特定のIDを持つユーザーを削除します。
Googleカレンダー情報を取得する

## はじめに
前に書いた記事を２か月ほど運用してみて、問題が見えてきました。

https://qiita.com/dmackey_2128/items/7a7e01ea47e745913fcb

## 問題点
私用や会社休みなどの在宅時に、自動でSNSにアップされて自身の姿が母親に見られてしまう・・！
覚えてたら９時直後にすぐOFFするけど、やっぱり人間は忘れる生き物。５回以上見られるという悲惨さ
暇つぶしに猫は見ても良いけど、私は見られたくないの。無意識な様子を見られるのって、言いようのない気持ち悪さ

## 自動ONに条件追加しよう
平日朝９時頃に自動ONしているけど、事前にONさせない仕組みを作ることをようやく決心。
スマホから操作したいので、googleカレンダー機能を使うのがよさそう。その備忘録な記事です。

## googleカレンダーの設定
webブラウザからアクセスして、「一般公開して誰でも利用できるようにする」のチェックを入れる。

<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625818/d09524bc-94dd-5fab-3b76-c581e97b275b.png">

## APIキーの取得
GCPにログインして、Google Calendar API を有効にして、APIキーを取得する。
<img width="700" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625818/bfce4ec2-2534-e200-00ad-449ed588c1d8.png">

## ソース
ChatGPTにもらったサンプルを調整して最終的にはこんな感じになった。

```python:weather.py
import requests
import json
from datetime import datetime, timedelta

# Google Calendar API のエンドポイント
CALENDAR_API_ENDPOINT = "https://www.googleapis.com/calendar/v3/calendars/{calendarId}/events"

# カレンダーID
calendar_id = あなたのカレンダーID(デフォルトだとgmailアドレス？)

# API キー
api_key = あなたのAPIキー

# カレンダーのイベント情報を取得する関数
def get_calendar_events(api_key, calendar_id, start_time, end_time):
    # エンドポイントのURLを構築
    endpoint_url = CALENDAR_API_ENDPOINT.format(calendarId=calendar_id)

    # パラメータを設定
    params = {
        "key": api_key,
        "timeMin": start_time,
        "timeMax": end_time,
    }

    try:
        # API リクエストを送信
        response = requests.get(endpoint_url, params=params)

        # レスポンスを JSON 形式で取得
        events_data = response.json()

        # イベント情報をリストにして返却
        events_list = []
        for event in events_data.get("items", []):
            event_info = {
                "Summary": event.get("summary", "No Summary"),
                "Start Time": event.get("start", {}).get("dateTime", "No Start Time"),
                "End Time": event.get("end", {}).get("dateTime", "No End Time"),
            }
            events_list.append(event_info)

        return events_list

    except requests.exceptions.RequestException as e:
        print("Error making API request:", e)

# 今日登録されているカレンダー情報に、カメラOFFで始まる件名が登録されているかどうか調べる
def sns_camera_judge():
    # 本日の日付を取得
    today = datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")
    # 本日の日付から1日後を計算
    tomorrow = (datetime.now() + timedelta(days=1)).strftime("%Y-%m-%dT%H:%M:%SZ")

    # カレンダーのイベント情報を取得
    infos = get_calendar_events(api_key, calendar_id, today, tomorrow)

    for info in infos:
        print(info)
        if info['Summary'].upper().startswith('カメラOFF'):
            print('今日はダメな日だ！！')
            return True
    return False

if __name__ == "__main__":
    sns_camera_judge()
```


## おわりに
これにてgoogleカレンダーに「カメラOFF ～～」と件名を入れれば、その日は自動ONされないことになり今回の目的は達成
skaffold buildでcacheが効いてビルドされない

# はじめに

検索してもなかなかでてこなくて時間がかかったのでまとめます

# 問題

パイプラインの中で以下のコマンドを実行しています

```
$ skaffold build
```

しかしDockerfileが新しくビルドされずに古いイメージをキャッシュで使ってしまいます

# 解決方法

以下のコマンドに変えることでキャッシュを使わないようにしました

````
$ skaffold build --cache-artifacts=false
```

# おわりに

他のパイプラインを参考にすることで解決できました。

# 参考

https://github.com/GoogleContainerTools/skaffold/issues/3050
FilePond ファイルサイズに制限をかける（バリデーション）

## はじめに
今回はFilePondを使ってアップロードした画像に対してサイズの制限をかける処理を実装します。
公式からプラグインが提供されているので、そちらを使用します。
FilePond公式ドキュメントは非常にわかりやすかったので、英語が得意の方は当記事を閲覧するよりも公式ドキュメントを参考にした方が良いかもしれません...
[FilePond公式 サイズ制御](https://pqina.nl/filepond/docs/api/plugins/file-validate-size/)

## FilePondを読み込む

今回はCDNを使用してFilePondを読み込みます
```html
<!-- FilePond ベースcss -->
<link href="https://unpkg.com/filepond/dist/filepond.css" rel="stylesheet" />
<!-- FilePond ベース -->
<script src="https://unpkg.com/filepond/dist/filepond.js"></script>
<!-- サイズ制御プラグイン -->
<script src="https://unpkg.com/filepond-plugin-file-validate-size/dist/filepond-plugin-file-validate-size.js"></script>
```

## 初期化

次にFilePondを初期化します。

```javascript
//初期化
FilePond.registerPlugin(FilePondPluginFileValidateSize);
```

※今回は1つのプラグインしか使用しませんが、複数プラグインを使用したい場合は以下のように記述してください
```javascript
//複数プラグインの初期化(画像プレビュー + 画像サイズ制限)
FilePond.registerPlugin(FilePondPluginImagePreview,FilePondPluginFileValidateSize);
```

## 組み込み

それでは実際にプラグインを組み込んでいきましょう！

### プロパティ

まずはこのプラグインで使用できるプロパティを確認しましょう

| プロパティ名 | デフォルト値 | 説明 |
|:-:|:-:|:-:|
| allowImagePreview  | true  | ファイルサイズの制御を有効(true)または無効(false)にする  |
| minFileSize  | null  | ファイルの最小サイズ。例 : `'750KB'`  |
| maxFileSize  | null  | ファイルの最小サイズ。例 : `'5MB'`  |
| maxTotalFileSize  | null  | リスト内のすべてのファイルの最大サイズ（maxFileSizeと同じ形式）  |
| labelMaxFileSizeExceeded  | `'File is too large'`  | サイズ上限を超える画像をアップロードした際に表示されるメッセージ  |
| labelMaxFileSize  | `'Maximum file size is {filesize}'`  | サイズ上限を超える画像をアップロードした際に表示される詳細メッセージ  |
| labelMaxTotalFileSizeExceeded  | `'Maximum total size exceeded'`  | ファイルの合計サイズが上限を超えた際に表示されるメッセージ  |
| labelMaxTotalFileSize  | `'Maximum total file size is {filesize}'`  | ファイルの合計サイズが上限を超えた際に表示される詳細メッセージ  |

今回はアップロードした画像の上限値を設定したいので、制御を有効にする`allowImagePreview`とファイルの上限値を設定する`maxFileSize`を使います。
出力するメッセージも変更したいので`labelMaxFileSizeExceeded`,`labelMaxFileSize`あたりも追加しましょう。

### 実装例

#### javascript
```javascript
document.addEventListener('DOMContentLoaded', function() {
    //初期化
    FilePond.registerPlugin(FilePondPluginFileValidateSize);

    //設定
    FilePond.setOptions({
        allowFileSizeValidation : true,//制御をON
        maxFileSize : '2MB',//上限値は2MB(2メガバイト)
        labelMaxFileSizeExceeded : 'ファイルサイズが大きすぎます！',
        labelMaxFileSize : 'ファイルサイズは2MBまでです',
    });

    //インスタンスを生成
    const inputElements = document.getElementById('filepond');//対象の要素を取得
    //const inputElement = document.querySelector('input[type="file"]'); この取得方法でもOK
    FilePond.create(inputElements);//実装
});
```
#### html

```html
<h1>FilePond</h1>
<input id="filepond" type="file"/>
```

## 結果
約4MBの画像ファイルを添付した結果、期待通りエラーになった。
設定したメッセージも確認できる。

![FilePond.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3687802/e4668453-87e2-a040-3434-6d715ef07cef.gif)

## まとめ
今回はFilePondでのファイルサイズの制御（バリデーション）を実装しました。
私自身がFilePondを組み込んだ時に、日本語の参考文献が少なかったのでこれからもFilePond系の記事を投稿しようかなと思っています。
少しでも役に立てれば幸いです。

## 参考文献
[FilePond公式 サイズ制御](https://pqina.nl/filepond/docs/api/plugins/file-validate-size/)
[FilePond公式 javascriptインストール](https://pqina.nl/filepond/docs/getting-started/installation/javascript/)
【ChatGPT有＋DALL-E3】から初めてのメッセージ！


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

　今回は、ChatGPTさんから、初めてのメッセージをもらいました。

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

　昨日（2024/02/05）、
　　東京は、
　　　お昼から雪になりました。

　今朝、
　　道路は、
　　　雪がシャーベット状に
　　　　なっていて、
　　　　　すべりまくり(=^･^=;

　みなさんは
　　大丈夫でしたか？
***
　昨日の
　　DALL-E3が
　　　DALL-E4だ、という話は
　　　　誰からも返事が
　　　　　ありません。

　今日、
　　Discordコミュニティに
　　　質問してみましたので
　　　　返答が得られたら
　　　　　報告します。
***
　さて、本題です。

　今回、
　　ChatGPTさんから
　　　初めてのメッセージを
　　　　もらいました。

「I'm sorry, but I can't fulfill this request.
（申し訳ないが、このリクエストには応えられない）」です。

　“どんなプロンプトを
　　与えたんだ？”と
　　　思われたかと思います。

　実は、
　　ちょうど、細菌や細胞を
　　　描画していまして
　　　　（X-Twitterで見掛けたので）
　　　　　試していたわけです。

　それで“これも出せるかな？”と
　　入力したのが、こちら。
　　　「精子。描画」

　これで初めてのメッセージを
　　ChatGPTさんから
　　　いただいたわけです。

　同じセッション内でしたから
　　そのまま、描画されるだろう、と
　　　思っていたのですが……

　そこで「精子ひとつ。描画」と
　　入れ直してみました。

　素直に
　　出してくれました。

　つまり、
　　「精子」は
　　　性的表現と捉えられた
　　　　わけです。

　でも
　　精子ひとつならば
　　　医学的・科学的な
　　　　ものなので、
　　　　　描画対象となる。

　そこで
　　いろいろと
　　　入れてみました。

　「18歳女性の水着姿」はNG。
　　けれど
　「20歳女性の水着姿」はOK。
　　というのもありました。

　まぁ、これは
　　倫理的にわかりますよね。
***
　ChatGPTさんとDALL-E3さんが
　　引っ掛かる単語や文章が
　　　わからないのは
　　　　困りますよね。

　そんなこと、
　　発表してくれるはずも
　　　ありませんし。

　自分たちで
　　コツコツと
　　　確認するしか
　　　　ありませんかねぇ？

　みなさんの
　　作品制作の糧に……
　　　ならんなぁ(=^･^=;

　今回は、ここまで。
AWS Route 53でのDMARCレコード設定ガイド

```
米国Google社が2024年2月以降、迷惑メール（なりすましメール）対策を強化した
「メール送信者のガイドライン(Email sender guidelines)」を適用すると発表しました。
```

1.  [SPFレコード設定の基本 – Googleを例にした実践ガイド](https://qiita.com/zhao-xy/items/749adb2c350f9bbf8440)
1. [Gmail（Google Workspace）とAWS Route 53を使用したDKIMレコード設定](https://qiita.com/zhao-xy/items/bb5bf364b4cb33aa98e6)
1. [AWS Route 53でのDMARCレコード設定ガイド](https://qiita.com/zhao-xy/items/5223a402a3d8c05b4ed1)

 ![unnamed.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155256/51fd5716-2a7d-0640-9dbf-cb556efc7646.png)
 
DMARC（Domain-based Message Authentication, Reporting, and Conformance）は、電子メールのセキュリティを強化し、フィッシングやスプーフィング攻撃から保護するために設計された認証プロトコルです。DMARCはSPF（Sender Policy Framework）およびDKIM（DomainKeys Identified Mail）の情報を利用して、メールが正当なものかどうかを判断し、不正なメールに対してどのように対応するかを指定します。

### DMARCレコードとは
DMARCレコードはDNSレコードの一種で、ドメインのメール認証ポリシーを定義し、受信メールサーバーに対して、SPFやDKIMの検証結果に基づいてメールをどのように扱うべきかを指示します。また、認証失敗のレポートを送信元ドメインに送るよう指示することもできます。

### AWS Route 53でのDMARCレコードの追加

1. AWSマネジメントコンソールにログイン
    AWSマネジメントコンソールにログインし、Route 53を選択します。
1. ホストゾーンの選択
    DMARCレコードを追加したいドメインのホストゾーンを選択します。
1. 新しいレコードの作成
    「レコードセットの作成」または「レコードを作成」ボタンをクリックして新しいレコードを追加します。    
1. レコードの詳細を入力    
    ・レコード名: _dmarc.example.com（example.comはあなたのドメイン名に置き換えてください）
    ・レコードタイプ: TXT
    ・TTL (Time to Live): 通常は3600秒またはそれ以上
    ・値: DMARCポリシーを定義する文字列。例えば、"v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com"（これはDMARCポリシーを監視モードに設定し、レポートをdmarc-reports@example.comに送信する設定です）
    ```
    DMARCポリシーの値
    DMARCレコードの値は、v=DMARC1で始まり、以下のようなタグを含むことができます：
    
    p: メールの取り扱いポリシー（例: none, quarantine, reject）
    rua: 認証失敗レポートの受信先メールアドレス
    pct: ポリシーが適用されるメールの割合（省略可能）
    ```
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155256/8643a285-bc92-06f0-ad2d-d72e08d1766a.png)

5. レコードの保存
    設定を確認したら、「レコードを作成」をクリックして保存します。

### 注意点
1. DMARCポリシーを導入する前に、SPFとDKIMが正しく設定されていることを確認してください。
2. p=noneから始めて、DMARCレポートを分析した後、ポリシーを段階的に厳格化することを推奨します。
3. DMARCレポートは、ドメインがどのように使用されているかを理解し、不正使用を検出するのに役立ちます。


https://support.google.com/a/answer/81126?hl=en&fl=1&sjid=12825274696225656735-NC
isoの多様な形式

ISO 8601形式で表される日時データは、非常に多様なパターンを持っています。これは、日時の表現が幅広い精度と様々な要素（年、月、日、時、分、秒、タイムゾーン）を含むことができるためです。ISO 8601は、単純な年月日から、時間を含むもの、さらにはタイムゾーン情報を含むものまで、多岐にわたる日時情報の表現をサポートしています。

### 主なISO 8601日時形式のパターン

1. **完全な日付**: `YYYY-MM-DD`（例: `2021-11-11`）

2. **年と週**: `YYYY-Www`または`YYYY-Www-D`（例: `2021-W45`、`2021-W45-4`）

3. **年と日**: `YYYY-DDD`（例: `2021-315`）

4. **完全な日時**: `YYYY-MM-DDTHH:mm:ss`（例: `2021-11-11T13:23:45`）

5. **秒の小数部分を含む日時**: `YYYY-MM-DDTHH:mm:ss.sss`（例: `2021-11-11T13:23:45.123`）

6. **タイムゾーン情報を含む日時**:
    - UTCオフセットを含む: `YYYY-MM-DDTHH:mm:ss+HH:MM`（例: `2021-11-11T13:23:45+09:00`）
    - Zを使用してUTCを示す: `YYYY-MM-DDTHH:mm:ssZ`（例: `2021-11-11T04:23:45Z`）

### 注意点

- ISO 8601は非常に柔軟であり、これらの基本的なパターンの組み合わせや、省略形（例えば、時分のみ: `HH:mm`）も許容します。

- タイムゾーンのオフセットは、`+HH:MM`、`+HHMM`、または単に`Z`（UTC）として表現することができます。

- 秒の小数部分は、より高い精度（例えば、ミリ秒、マイクロ秒）を必要とするアプリケーションで使用されます。小数点以下の桁数は、使用するアプリケーションによって異なります。

- 実際のアプリケーションでは、これらのパターンのいずれかを選択して使用することが多いですが、特に国際的なコンテキストや、異なるシステム間で日時データを交換する場合には、ISO 8601形式の利用が推奨されます。

このように、ISO 8601は多様な日時表現をサポートしており、その柔軟性が幅広い用途での利用を可能にしています。
【備忘録】Next.js 公式チュートリアル Chapter-2 CSS Styling

[前回](https://qiita.com/filmoet/items/6eab8483fe5b33ddf319)
## 当チャプターの内容
- グローバルCSSファイルの適用方法
- TailwindCSSとCSSモジュールの2つのスタイリング方法
- ```clsx```ユーティリティパッケージを使って条件付きのクラス名を追加する方法

なんか最後のやつがよくわからんですが、やっていきましょう。

[【公式ドキュメント】Next.js Chapter-2 CSS Styling](https://nextjs.org/learn/dashboard-app/css-styling)

### Global styles
```/app/ui/global.css```を弄るとすべてのルート（ページ）にCSSを適用することができるらしい。
これをグローバルスタイルと呼んでいるらしい。
適用するには```/app/layout.tsx```にglobal.cssをインポートしましょう。
ということで、```layout.tsx```を編集します。
```diff_typescript:lauout.tsx
+ import '@/app/ui/global.css';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}
```
そして立ち上げたローカルのページを見てみると...

<img src="https://i.gyazo.com/7f5bef0813ada8822b080252ed3acf61.png">

WoWスタイリングされてるじゃないすか！

### TailwindCSS
TailwindCSSはCSSのフレームワークで流行りのやつですね。（こういう情報はなんとなく知ってる）
最近はshadcn/uiとかも巷で噂になってたりしますね。

TailwindCSSではCSSファイルにスタイルを記述するのではなくてタグ内の```className```にスタイルを記述していきます。
```html
<h1 className="text-blue-500">I'm blue!</h1>
```
このようにh1タグに```text-blue-500```とクラス名を付与するとテキストが青色になります。
詳しくは[TailwindCSS公式ドキュメント](https://tailwindcss.com/docs/installation)をみよう！

### CSS Modules
CSSモジュールを使えば自分オリジナルのクラス名を追加することができる
```css:/app/ui/home.module.css
.shape {
  height: 0;
  width: 0;
  border-bottom: 30px solid black;
  border-left: 20px solid transparent;
  border-right: 20px solid transparent;
}
```
このように記載し、対象のページでインポートすればオリジナルのスタイリングをオリジナルのクラス名で呼び出すことができる！
```typescript:/app/page.tsx
import styles from '@/app/ui/home.module.css';
<div className={styles.shape} />;
```
今回のコースではTailwindCSSを主に使うため紹介程度です。

### Using the clsx library to toggle class names
ついによくわからんのきたーという感じですが、意外とわかりました。
```clsx```というのはライブラリのことで、その時の状態や条件に応じてクラス名を変更することができるらしい。
```diff_typescript:/app/ui/invoices/status.tsx
import clsx from 'clsx';
 
export default function InvoiceStatus({ status }: { status: string }) {
  return (
    <span
      className={clsx(
        'inline-flex items-center rounded-full px-2 py-1 text-sm',
        {
+         'bg-gray-100 text-gray-500': status === 'pending',
+         'bg-green-500 text-white': status === 'paid',
        },
      )}
    >
    // ...
)}
```
上記コードでは状態```status```が
```pending```のときは背景・テキストをグレーに
```paid```のときは背景を緑・テキストを白に
設定するということをやってますね。

### Other styling solutions
TailwindCSS以外のスタイリング方法ですが、
- ```.css```や```.scss```等の普通にSassも使えます
- ```styled-jsx``` ```styled-components``` や ```emotion``` 等のCSS-in-JSライブラリも使えます

## 終了！！
以上でChapter-2 CSS Stylingは終了でした。
次回はChapter-3 Optimizing Fonts and Imagesです！
Gmail（Google Workspace）とAWS Route 53を使用したDKIMレコード設定

```
米国Google社が2024年2月以降、迷惑メール（なりすましメール）対策を強化した
「メール送信者のガイドライン(Email sender guidelines)」を適用すると発表しました。
```

1.  [SPFレコード設定の基本 – Googleを例にした実践ガイド](https://qiita.com/zhao-xy/items/749adb2c350f9bbf8440)
1. [Gmail（Google Workspace）とAWS Route 53を使用したDKIMレコード設定](https://qiita.com/zhao-xy/items/bb5bf364b4cb33aa98e6)
1. [AWS Route 53でのDMARCレコード設定ガイド](https://qiita.com/zhao-xy/items/5223a402a3d8c05b4ed1)

 ![unnamed.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155256/51fd5716-2a7d-0640-9dbf-cb556efc7646.png)
 
DKIM（DomainKeys Identified Mail）は、メール送信の真正性を保証し、スパムやフィッシングから保護するために設計された電子メール認証プロトコルです。DKIMを使用することで、電子メールが送信元のドメインから正式に送信されたものであり、途中で内容が改ざんされていないことを受信側が検証できます。

### DKIMとは？
DKIMは、送信ドメインの公開キーをDNSにレコードとして公開し、送信メールにデジタル署名を付与することで機能します。受信側は、この公開キーを使用してメールに付された署名を検証し、メールの真正性を確認します。
今回にはGmail（Google Workspace）で送信するメールにDKIMを設定し、AWS Route 53を使用してDKIMレコードをDNSに追加を行います。

### Gmail（Google Workspace）でのDKIMの設定

1. Google Adminコンソールへログイン: Google Workspaceの管理者として、[Google Adminコンソール](https://admin.google.com/)にアクセスします。

1. アプリ設定に移動: ダッシュボードから「アプリ」>「Google Workspace」>「Gmail」>「認証」に進みます。

1. DKIMキーの生成: 「[認証](https://admin.google.com/ac/apps/gmail/authenticateemail)」セクションで、「ドメインキーを生成」をクリックし、ドメインを選択します。キーの長さを選ぶオプションがある場合は、2048ビットを推奨します。

1. DKIMキーの詳細を確認: キーが生成されたら、その詳細を確認します。これには、セレクターと公開キーが含まれます。セレクターは、特定のDKIMキーを指すために使用される一意の名前です。

### AWS Route 53でのDKIMレコードの追加

1. AWSマネジメントコンソールにログイン: AWSアカウントにログインし、[Route 53](https://us-east-1.console.aws.amazon.com/route53/v2/home?region=ap-northeast-1#Home)のダッシュボードにアクセスします。

1. ホストゾーンの選択: DKIMレコードを追加したいドメインのホストゾーンを選択します。

1. 新しいレコードの作成: 「レコードセットの作成」または「レコードの作成」ボタンをクリックして新しいレコードを追加します。

1. レコードの詳細を入力:    
    ・レコード名: Google Adminコンソールで提供されたセレクターを使用して、レコード名を形成します。通常はselector._domainkey.example.comの形式になります。    
    ・レコードタイプ: TXTを選択します。    
    ・TTL (Time to Live): 3600またはそれ以上を設定します。    
    ・値: Googleから提供された公開キーの情報を入力します。これはv=DKIM1; k=rsa; p=公開キーの文字列の形式で提供されます。

1. レコードの保存: 設定を確認したら、「レコードを作成」をクリックして保存します。

### 設定後の確認
DKIMレコードの伝播: DNSレコードの更新が全世界に伝播するのを数時間から48時間待ちます。
検証: Google Adminコンソールに戻り、「認証」セクションで「ドメインキーを有効にする」を選択してDKIMを有効化します。また、オンラインのDKIM検証ツールを使用して、設定が正しく機能しているか確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155256/354da25f-aaf1-356a-0520-32ad539cba52.png)
windowsでiverilog その142

# 概要　
windowsでiverilogやってみた。
cpu見つけたので、調べてみた。

# 参考にしたページ


https://qiita.com/yasuo-ozu/items/6b14cc514e818dc1cfbb

https://emu.kemuide.openwaseda.net/index.html

# CPU名称

- よくわからないので、「KEMU」にする。

# CPUタイプ
- レジスタマシーン
# レジスタ

|レジスタ|長さ|名前|
|:-|:-|:-|
|ACC| 8bit|アキュムレータ
|IX  |  8bit|インデックスレジスタ
|IR   | 8bit|インストラクションレジスタ
|PC  |  8bit|プログラムカウンター
# 命令長
8bit 1から２ワード
上４bitで、判別可能

|8|7|6|5|アセンブリ|命令長|
|:-|:-|:-|:-|:-|:-|
|0|0|0|0|NOP HLT|1
|0|0|0|1|IN OUT|1
|0|0|1|0|SCF RCF|1
|0|0|1|1|B**|2
|0|1|0|0|RA LA RL LL|1
|0|1|0|1|index|*
|0|1|1|0|LD|1-2
|0|1|1|1|ST|1-2
|1|0|0|0|SBC|1-2
|1|0|0|1|ADC|1-2
|1|0|1|0|SUB|1-2
|1|0|1|1|ADD|1-2
|1|1|0|0|EOR|1-2
|1|1|0|1|OR|1-2
|1|1|1|0|AND|1-2
|1|1|1|1|CMP|1-2

# I/O
OUT, IN命令があり、 OBUF_FLAGとIBUF_FLAGがある。
8bitパラレル。

# メモリー
- ROM プログラム
- RAM データ

# 分岐は、絶対アドレッシング

# 関節アドレッシング有り

LD, ST, SBC, ADC, SUB, ADD, EOR, OR, AND, CMP

```
LD ACC, IX         # IXの値をACCに書き込む
LD ACC, 01h        # ACC に 1(16進数)を書き込む
LD ACC, [00h]      # ACCにプログラムメモリの0番地の値を読み込む
LD ACC, (00h)      # ACCにデータメモリの0番地の値を読み込む
LD ACC, (100h)     # 上と同様
LD ACC, [IX + 00h] # プログラムメモリのIX番地をACCに読み込む
LD ACC, (IX + 02h) # データメモリのIX+02番地をACCに読み込む
LD IX, (ACC + 00h) # このようなことはできません!
LD ACC, (IX)       # このような書き方も出来ません! (IX+00h と書けば良い)
ST ACC, (IX + 00h) # ACCの値をデータメモリのIX番地に書き込む
ST ACC, IX         # 第2オペランドにレジスタは指定できません!
ST ACC, 01h        # 第2オペランドに即値は指定できません!
```

# アセンブラ

|アセンブリ|動作|
|:-|:-|
|NOP| no op|
|HLT| pc->pc |
|IN|data->acc|
|OUT| acc->data|
|RCF| 0->CF |
|SCF| 1->CF |
|BA	|if	true
|BVF|if		VF==1
|BNZ|if		ZF==0
|BZ	|if	ZF==1
|BZP|if		NF==0
|BN	|if NF==1
|BP	|if (NF or ZF) == 0
|BZN|if	 (NF or ZF) == 1
|BNI|if		IBUF_FLAG == 0
|BNO|if		OBUF_FLAG == 1
|BNC|if		CF == 0
|BC	|if	CF == 1
|BGE|if		(VF xor NF) == 0
|BLT|if		(VF xor NF) == 1
|BGT|if	((VF xor NF) or ZF) == 0
|BLE|if		((VF xor NF) or ZF) == 1|
|SRA| r + cf >> |
|SLA| cf + r << |
|SRL| r >>
|SLL| r <<
|RRA| r >> cf
|RLA| r << cf
|RRL| >> r + cf
|RLL| << r + cf
|LD|**->r|
|ST|r->**|
|ADD|	r0 + r1 ->r0
|ADC|	r0 + r1 + cf -> r0
|SUB|	r0 - r1 -> r0
|SBC|	r0 -r1 - cf -> r0
|CMP|	r0 - r1
|AND|	r0 and r1 -> r0
|OR	|r0 or r1 -> r0
|EOR|	 r0 xor r1 -> r0


以上。
【C#】Aspose.cellsとOpenFileDialogを使ってみた

C#で作成するツールにて、ダイアログを表示してExcelのパスを取得し、該当Excelを開いて内容を取得する必要がでたため、Aspose.cellsとOpenFileDialogで実装を行った。
以下に簡単にAspose.cellsとOpenFileDialogについてまとめます。

# Aspose.cellsとは何か？
XLS を作成するための高速 C# ライブラリ。これは、XLSX、PDF、および .NET フレームワーク、.NET コアまたは Mono プラットフォーム上のその他の多くの形式をインポートおよびエクスポートするためのApiです。
**⇒Excelの操作が簡単にできるようになるApiということ。**

## 導入方法
dllとライセンスファイルをプログラムに置くだけでした。

## 使用例
###### ライセンス設定
```
// ライセンス設定(Aspose.Cells.licを「埋め込まれたリソース」に設定すること)
Aspose.Cells.License license = new Aspose.Cells.License();
license.SetLicense("Aspose.Cells.NET.lic");
```

###### ワークブックを取得する
```
//Create a workbook object
Workbook workbook = new Workbook(INPUTFILEPATH);　⇒INPUTFILEPATH：読み込みたいExcelのパス 
```
###### ワークシートを取得する。（1ページ目を取得）
```
//Get the first worksheet in the workbook
Worksheet worksheet = workbook.Worksheets[0];
```

###### セルの内容を取得
```
//Get the cells collection in the sheet
Cells cells = worksheet.Cells;
```
###### ワークシートから空白行/列を削除する。
```
 worksheet.Cells.DeleteBlankRows();
 worksheet.Cells.DeleteBlankColumns();
```

###### データテーブルにExcelから取得内容を格納
```
// Exporting the contents of 7 rows and 2 columns starting from 1st cell to DataTable
DataTable dataTable = worksheet.Cells.ExportDataTableAsString(int firstrow, int firstColumn, int totalrows, int totalColumns, bool exportColumnName);
```
###### 例：各シート毎に空の判定を行う。
```
for (int i = 0; i<workbook.Worksheets.Count; i++)
{
    Worksheet worksheet = workbook.Worksheets[i];
    Cells cells = worksheet2.Cells;
    if (cells.Count > 0)
    {
         // 入力あるシートの処理
    }
    else
    {
        //　空シートの処理
    }
}
```

# ダイアログを表示する方法
## OpenFileDialog クラス
ユーザーにファイルを開けるように指示するダイアログ ボックスを表示します。 このクラスは継承できません。

```
var fileContent = string.Empty;
var filePath = string.Empty;

using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
    openFileDialog.InitialDirectory = "c:\\";
    openFileDialog.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
    openFileDialog.FilterIndex = 2;
    openFileDialog.RestoreDirectory = true;

    if (openFileDialog.ShowDialog() == DialogResult.OK)
    {
        //Get the path of specified file
        filePath = openFileDialog.FileName;

        //Read the contents of the file into a stream
        var fileStream = openFileDialog.OpenFile();

        using (StreamReader reader = new StreamReader(fileStream))
        {
            fileContent = reader.ReadToEnd();
        }
    }
}

MessageBox.Show(fileContent, "File Content at path: " + filePath, MessageBoxButtons.OK);
```
JavaでISO日時をフォーマットする方法

ISO 8601は国際標準化機構(ISO)によって定められた日時の表記方法であり、国際的なデータ交換において広く利用されています。JavaでISO 8601形式の日時を扱う際、java.timeパッケージは強力なツールセットを提供します。この記事では、任意の形式のISO日時文字列を特定の形式(2021-11-11T13:23:45,123456+09:00)に変換する方法を紹介します。

日時のパース: 最初のステップは、入力されたISO日時文字列をLocalDateTime、ZonedDateTime、またはOffsetDateTimeオブジェクトにパースすることです。入力形式が事前にわかっていない場合は、DateTimeFormatterを使って柔軟に対応することが可能です。
	2.	日時の変換: 日時オブジェクトを目的の形式に変換します。このプロセスでは、DateTimeFormatterをカスタマイズして使用します。
	3.	結果の出力: 最終的に、変換された日時を文字列として出力します。

Javaコード

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

public class IsoDateTimeFormatter {
    public static void main(String[] args) {
        String inputIsoDateTime = "2021-11-11T13:23:45.123456+09:00"; // 例としてこの入力を使用
        String outputIsoDateTime = formatIsoDateTime(inputIsoDateTime);
        System.out.println(outputIsoDateTime);
    }

    public static String formatIsoDateTime(String inputIsoDateTime) {
        try {
            // 入力された日時を解析
            ZonedDateTime dateTime = ZonedDateTime.parse(inputIsoDateTime);
            // 目的のフォーマットを定義
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss,SSSSSSXXX");
            // 日時を変換して文字列として返す
            return dateTime.format(formatter);
        } catch (DateTimeParseException e) {
            // 日時の解析に失敗した場合は、エラーメッセージを返す
            return "Invalid ISO DateTime format.";
        }
    }
}

このコード例では、ZonedDateTime.parseメソッドを使用してISO日時文字列を解析し、カスタマイズされたDateTimeFormatterを使用して目的の形式に変換しています。この例では、ナノ秒までの精度を含む特定の形式を指定していますが、DateTimeFormatterのパターンを調整することで、異なる形式にも対応可能です。
シミュレーションの練習

https://paiza.jp/works/mondai/c_rank_level_up_problems/c_rank_simulation_step2

```py
n = int(input())
a,b = map(int,input().split())
paiza_score = 1
kirijima_score = 1
cnt = 0

while n > kirijima_score:
    #paiza_turn
    kirijima_score = paiza_score * a
    #kirijima_turn
    paiza_score += kirijima_score % b
    #turn_end
    cnt += 1
    
print(cnt)


```
これでいいかな？と思ったんですがだめでした。
じっくり問題読むと、つまりキリジマのスコアがnを超えたときってことなので
それはつまり、キリジマのスコアが動いた時に判定しなきゃ意味がないんですね。
だからwhileの条件判定じゃだめってこと。
だから

```py
n = int(input())
a,b = map(int,input().split())
paiza_score = 1
kirijima_score = 1
cnt = 0

#while条件はTrueに変更
while True:
    kirijima_score += paiza_score * a
    #この時点で判定する
    if n < kirijima_score:
        break
        
    #kirijima_turn　
    paiza_score += kirijima_score % b
    #turn_end
    cnt += 1
    
print(cnt)
```

あれ、、、だめでしたね。。
こうするとテストケースが１になってしまいました。
テストケースは６と３，２でしたね
n = 6
a,b = 3,2
kirijima = 4
paiza = 3
cnt = 1

で次に、
kirijima = 13
で超えたのでおわり
cnt = 1のままでしたね。。。
ってことは回数を増やすのは最初でないとだめだ。

```py
n = int(input())
a,b = map(int,input().split())
paiza_score = 1
kirijima_score = 1
cnt = 0

#while条件はTrueに変更
while True:
    cnt += 1
    kirijima_score += paiza_score * a
    #この時点で判定する
    if n < kirijima_score:
        break
    paiza_score += kirijima_score % b
    
    
print(cnt)
```
OKでした。
なかなかここらへん、どこで回数増やすべきなのかってのが
分かりづらいんですよね。。。
一番最初に回数を増やすべきか、最後にするべきかの判断をどう考えればいいかが、難しいです。