OmniAICreator/Qiita-1.07M huggingface dataset:
HTTPについて

## HTTPとは
Hyper Text Transfer Protocolの略で、HTMLで書かれた文書などの情報をやり取りする時に使われる通信規則（プロトコル）のこと

## プロトコルとは
コンピュータでデータをやりとりするために定められた手順や規約、信号の電気的規則、通信における送受信の手順などを定めた規格のこと

## HTTPリクエストとは
ウェブブラウザがウェブサーバーに対して情報を要求するためのメッセージです。たとえば、ウェブサイトを開くとき、ブラウザはそのサイトのサーバーに HTTP リクエストを送信します。
HTTPリクエストはリクエストライン、ヘッダ、メッセージボディの 3 つの要素から構成されています。

### リクエストライン
リクエストラインはリクエストの最初の行で、以下の 3 つの部分から成ります

1. HTTPメソッド：リクエストの種類を指定します
    HTTP メソッドはリクエストの種類を指定し、サーバーがリクエストをどのように処理するかを決定します。主なメソッドには以下のものがあります：
    GET：サーバーからリソースを取得するために使用します。例えば、ウェブページを表示する時に使用されます。
    POST：サーバーにデータを送信して新しいリソースを作成するために使用します。例えば、フォームに入力されたデータを送信する時に使用されます。
    PUT：サーバー上の既存のリソースを更新するために使用します。例えば、既存のユーザーデータを更新する時に使用されます。
    DELETE：サーバー上のリソースを削除するために使用します。例えば、ユーザーアカウントを削除する時に使用されます。
    PATCH：リソースの一部を更新するために使用します。PUT が全体を更新するのに対して、PATCH は部分的な更新に適しています。
    
2. リクエストURL：リクエスト対象のリソースを指定します（例：/index.html）
3. HTTPバージョン：使用する HTTP のバージョンを指定します（例：HTTP/1.1）
例：GET /index.html

### ヘッダ
ヘッダはリクエストに関する追加情報を提供するための部分です。各ヘッダはキーと値のペアで表され、リクエストに関する様々な情報を含みます。

Host：リクエスト対象のサーバーのホスト名
User-Agent：リクエストを送信しているクライアントの情報
Content-Type：送信するデータのタイプ
     例：
     Host: www.example.com
     User-Agent: Mozilla/5.0
     Content-Type: application/json

### メッセージボディ
メッセージボディはリクエストの内容そのもので、主に POST や PUT リクエストで使用されます。例えば、フォームのデータや JSON データなどが含まれます。
    例：
    
     {
         "username": "example",
         "password": "password123"
     }

## HTTPレスポンスとは
ウェブサーバーがウェブブラウザなどのクライアントからの HTTP リクエストに対して送信するメッセージです。リクエストに対する結果やデータをクライアントに返します。
HTTPレスポンスはステータスライン、ヘッダ、メッセージボディの 3 つの要素から構成されています。

### ステータスライン
ステータスラインはレスポンスの最初の行で、以下の 3 つの部分から成ります：

1. HTTP バージョン：使用している HTTP のバージョンを指定します（例：HTTP/1.1）
2. ステータスコード：リクエストの処理結果を示す 3 桁の数字
HTTP ステータスコードは、サーバーがクライアントのリクエストをどのように処理したかを示す 3 桁の数字です。ステータスコードにはいくつかのカテゴリがあります。

  200 OK：リクエストが成功し、正常に処理されました。通常、GET リクエストのレスポンスとして使用されます。
  201 Created：リクエストが成功し、新しいリソースが作成されました。通常、POST リクエストのレスポンスとして使用されます。
  204 No Content：リクエストは成功しましたが、返すべきコンテンツがありません。通常、リソースの削除や更新に使用されます。
  301 Moved Permanently：リクエストしたリソースが恒久的に新しい URL に移動しました。クライアントは新しい URL に自動的にリダイレクトされます。
  400 Bad Request：リクエストが不正であり、サーバーが処理できません。クライアント側のエラーです。
  401 Unauthorized：認証が必要であり、クライアントは認証情報を提供する必要があります。
  403 Forbidden：リクエストは理解されましたが、サーバーはそれを拒否しています。認証してもアクセスが許可されない場合に使用されます。
  404 Not Found：リクエストしたリソースが見つかりませんでした。存在しない URL にアクセスした場合に使用されます。
  500 Internal Server Error：サーバー内部でエラーが発生し、リクエストを処理できません。サーバー側のエラーです。
3. ステータスの理由句：ステータスコードを説明する短いテキスト
例：HTTP/1.1 200 OK

### ヘッダ
ヘッダはレスポンスに関する追加情報を提供するための部分です。各ヘッダはキーと値のペアで表され、レスポンスに関する様々な情報を含みます。

Content-Type：レスポンスのデータの種類を示します（例：Content-Type: text/html）
Content-Length：レスポンスボディの長さを示します（例：Content-Length: 1234）
Set-Cookie：クッキーを設定するためのヘッダ（例：Set-Cookie: sessionId=abc123; Path=/;）
     例：
     Content-Type: text/html
     Content-Length: 1234
     Set-Cookie: sessionId=abc123; Path=/

### メッセージボディ
メッセージボディはレスポンスの内容そのもので、クライアントに返すデータが含まれます。例えば、HTML ページや画像、JSON データなどが含まれます。

 例：
```
<html>
     <head><title>Example Page</title></head>
     <body><h1>Hello, world!</h1></body>
</html>
```
なぜPythonはファイルを分けないの？C++と比較したファイル整理の話　part2

## はじめに


前回は、なぜC++はヘッダーファイルやMainファイルに分けるのかといったお話をしました。今回は、Python側に目を向けて、**なぜPythonは反対にファイルを分割せずとも実装できるのかについてお話していきます。**




Pythonなどのスクリプト言語では、C++のような分割が必要ない理由はいくつかあります。

### 1. 動的型付けとインタプリタ
動的型付け: Pythonは動的型付けの言語であり、変数の型を明示的に宣言する必要がありません。これにより、ヘッダーファイルで型やクラスを宣言する必要がなくなります。
インタプリタ: Pythonはインタプリタ言語であり、コードが逐次実行されます。C++のようにコンパイル時にすべてのコードを解析する必要がないため、分割の必要性が減ります。

### 2. モジュールとパッケージ
モジュール: Pythonでは、1つのファイルが1つのモジュールとして扱われます。モジュールをインポートすることで、他のファイルやスクリプトでその機能を利用できます。この仕組みにより、ヘッダーファイルと実装ファイルに分ける必要がなくなります。
パッケージ: 複数のモジュールをディレクトリ構造で整理することにより、大規模なプロジェクトでも管理が容易になります。__init__.pyファイルを使用することで、ディレクトリをパッケージとして扱うことができます。



### 3. 簡潔な構文と設計哲学
簡潔な構文: Pythonの設計哲学は、「シンプルで明快なコード」を重視しており、コードの分割を最低限に抑えています。このため、クラスや関数の宣言と実装を1つのファイルにまとめることが推奨されます。
Pythonicな設計: Pythonコミュニティでは、コードをシンプルかつ可読性の高いものにすることが推奨されており、過度な分割を避ける傾向があります。



### 4. 開発とデプロイの容易さ
迅速な開発: スクリプト言語の特性上、開発者はすぐにコードを実行してテストできます。これにより、宣言と実装を分ける必要が減り、開発スピードが向上します。
デプロイの簡便さ: Pythonスクリプトはそのままデプロイできるため、ファイルの分割がデプロイの複雑さを増すことはありません。



### 5. 標準ライブラリとサードパーティライブラリ
豊富な標準ライブラリ: Pythonの標準ライブラリは非常に充実しており、多くの機能がすでにモジュール化されています。開発者は必要な機能をインポートするだけで済みます。
サードパーティライブラリ: PIPなどのパッケージ管理システムを利用して、簡単に外部ライブラリをインストールし、利用できます。



## まとめ
これらの理由により、PythonではC++のようなヘッダーファイルと実装ファイルの分割が必要ないのです。
AWSに関わる単語を整理する

# この記事の趣旨
AWSを初めて学ぶ際、大量の耳慣れない単語に辟易することは必至。インフラの具体的な構築手順などは慣れていくしかないとして、概念的なものはできるだけ整理しておきたいところ。そこで、自分の理解度を確認・向上させるため学んだ単語を使って主要なサービスを正しく説明してみたい。項目を分けてもよい。
# 問題 次の単語を全て用いてAWSを説明せよ。
AWS, VPC, RDS, アベイラビリティゾーン, ドメイン, オブジェクト, インターネットゲートウェイ, EC2, セキュリティグループ, ELB, IAM, サブネット, ルートテーブル, Route53, インスタンス, バケット, S3, クラウドコンピューティングサービス, リージョン, SSH, AMI,
# 解答例
### 総論
AWSとは、Amazonが提供するクラウドコンピューティングサービスであり、そのシェア率はGCP、Azureを抑えて世界最大である。主要なサービスにVPC、EC2、RDS、S3、Route53などがある。AWSアカウント作成時には、すべての権限を有するルートユーザーが作成されるが、意図しない操作による事故を防ぐため、普段は作業用のIAMユーザーを使用することが推奨される。
### VPC
VPCとは仮想ネットワークを構築するサービスである。VPCは単一のリージョンのもとにしか作成できないが、アベイラビリティゾーンを跨いで作成することはできる。
サブネットを作成してネットワークを分割することで、通信の範囲などを細かく設定することができる。VPCにインターネットゲートウェイを設置することでインターネットとの接続が可能になり、各サブネットにルートテーブルを設定することで通信を振り分けることができる。
### EC2
EC2は仮想サーバーを構築するサービスである。必要な情報がまとめられたテンプレートであるAMIからインスタンスを作成していく。ファイアウォールの役割を担うセキュリティグループを設定することで、通してよい通信と通してはいけない通信を設定できる。サーバーにインストールしたソフトウェア（Apacheなど）を操作する際には、SSHで接続することになる。サーバーにアクセスが集中し過ぎてしまうようであれば、ELBを用いて負荷分散させるとよい。
### RDS
RDSはマネージドな、つまり運用・管理の大半をAWSが代わりにやってくれる、リレーショナルデータベースサービスである。インスタンスとしてVPC上に設置していくという点でEC2と類似する。RDSを使わずにEC2を設置してDBのソフトウェアをインストールする方法もあるため、比較が必要。
### S3
S3はクラウドストレージサービスであり、保存場所であるバケットにオブジェクトとしてデータが格納される。
### Route53
Route53はAWSが提供するDNSサービス、つまりドメイン名をIPアドレスに変換するサービスである。
# 終わりに
頭に浮かんだ用語を雑に羅列して問題設定するだけでも「こんな理解であってるんだっけ」とか「これを説明するにはあれが必要だな」となって整理できるので、なかなか良い方法だと思う。誤りがあれば指摘していただきたい。
なぜC++はファイルを分けるの？Pythonと比較したファイル整理の話　part1

## 　はじめに


PythonからC++に書き替える必要性が出てきた時に、**Pythonはなぜファイルに分けず、C++は慣習として分けるのか**疑問に思ったのでメモがてら投稿してみました。


### 1. 分離と再利用

ヘッダーファイル (.h/.hpp): これはクラスや関数の宣言を含みます。外部に公開するインターフェース（API）を定義します。例えば、クラスのメンバ関数のプロトタイプ、メンバ変数、および定数の宣言が含まれます。
実装ファイル (.cpp/.cxx): これはクラスや関数の実装を含みます。実際の処理ロジックが書かれています。
この分離により、実装の詳細を隠蔽し、ユーザーがヘッダーファイルをインクルードするだけで機能を利用できるようにします。

### 2. コンパイル時間の短縮
ヘッダーファイルが変更されない限り、実装ファイルの変更はヘッダーファイルをインクルードしている他のファイルに影響を与えません。これにより、コンパイル時間を短縮できます。
ヘッダーファイルが頻繁に変更されると、それをインクルードしているすべてのファイルが再コンパイルされる必要がありますが、実装ファイルの変更は、その実装ファイル自身とそれを直接リンクしているファイルにのみ影響します。


### 3. コードの管理とモジュール化
大規模なプロジェクトでは、コードを管理しやすくするために、クラスや関数の宣言と実装を分けることが推奨されます。これにより、コードの可読性が向上し、メンテナンスが容易になります。
モジュールごとにファイルを分けることで、コードの再利用性が向上し、特定の機能やクラスに焦点を当てて作業ができます。

### 4. 言語の仕様と歴史的経緯
C++はC言語の拡張として設計されており、C言語のヘッダーファイルと実装ファイルの分割という伝統を引き継いでいます。
プログラムのインターフェースと実装を分けることにより、他のプログラムがそのインターフェースを利用できるようにするという考え方は、モジュール化されたソフトウェア設計の基本的な原則の一つです。

## まとめ

以上の理由からC++ではヘッダーファイルと実装ファイルにコードを分割することが一般的です。一方、Pythonのようなスクリプト言語では、このような分割が必要ないため、コードが1つのファイルにまとまっていることが多いようです。Pythonで分割が必要ない理由については別途投稿したいと思います。
Clojureを使って競技プログラミングに参加する

この記事では競技プログラミングにClojureという言語を使用して参加する方法を紹介していきます。

## Clojureとは
人によってはあまり聞き馴染みのない言語かもしれませんが、れっきとしたプログラミング言語です。
綴りは`Closure`ではなく`Clojure`です。（前者はJavaScriptなどで使われる単語の方です。）
Java仮想マシン（JVM）上で動作する関数型でLisp派生の言語です。（Lispについては[Wikipedia](https://ja.wikipedia.org/wiki/LISP)などをご参照ください。）

## 競技プログラミングとは
国内で最も有名な競技プログラミングサイトである[AtCoder](https://atcoder.jp/)によると、以下のように説明されています。
>決められた条件のもとで与えられた問題、課題をプログラミングを用いて解決し、その過程や結果を競うもの

たとえば以下のような問題文があったとします。
```
整数Aと整数Bが与えられます。
AとBの合計値を出力してください。
```
それに対して以下のような制約がついています。
```
- 入力は全て整数である。
- 0 ≦ A, B ≦ 100
```
そして、入力は以下の形式で標準入力から与えられます。
```
A B
```
この問題を解くプログラムを実装するスピードを競うのが競技プログラミングです。
（厳密な答えが存在しない[ヒューリスティックコンテスト](https://atcoder.jp/contests/ahc003?lang=ja#:~:text=AtCoder%20Heuristic%20Contest%EF%BC%88AHC%EF%BC%89%E3%81%A8%E3%81%AF%EF%BC%9F)というのも開催されていますが、ここでは与えられた入力値に対して明確に答えが存在する一般的なコンテストについて説明していきます。）

上述した問題をPythonで回答してみると、以下のようになると思います。
```Python
A, B = map(int, input().split())
sum = A + B
print(sum)
```
`input()`で標準入力を受け取り、`.split()`でlist化してから`map()`関数でそれぞれの値を`int`型にキャストし、AとBに代入しています。
それらを足し合わせた値を`sum`に代入し、`print(sum)`で標準出力しています。

これをClojureでやっていきたいと思います。

## 競プロ（AtCoder）の問題をClojureで解く
実際に過去に出題された問題を例にやっていきます。
AtCoder Beginner Contest（通称ABC）の128から[Apple Pie](https://atcoder.jp/contests/abc128/tasks/abc128_a)という問題を解いていきます。
詳細はリンク先を参照いただければと思いますが、この問題では与えられたA個のリンゴを全て砕いてそれぞれ3個の欠片にして、すべての欠片を使っていくつアップルパイを作ることができるかを求めればよいでしょう。

ではまず、標準入力を受け取ります。
`read`関数を使用すると標準入力を受け取ることができます。Clojureでは半角スペースを含んだ入力値を一度で受け取ることができなさそうなので、AとPで別々に標準入力から受け取りそれぞれをAとPという変数に束縛していきます。（Clojureでは変数に値を代入することを「束縛」といいます。）
変数の定義には`def`というマクロを使用するので、以下のようになります。
```Clojure
(def A (read))
(def P (read))
```
Clojureでは数値を入力すると自動的にlong型だと認識してくれるようなので、型キャストの必要はありません。
なので、次にAこのリンゴを全て砕いて3個の欠片にするので、Aを3倍していきます。
```Clojure
(def triple-a (* A 3))
```
そしてPと足し合わせます。
```Clojure
(def all-pieces (+ triple-a P))
```
作ることのできるアップルパイの数を求めるには、`all-pieces`を2で割った商の整数部分を求めれば良いです。
Clojureでは`quot`という関数を使用すると小数点以下を切り捨てた値を取得することができます。
```Clojure
(def ans (quot all-pieces 2))
```
これを`println`関数で出力すれば完了です。
```Clojure
(println ans)
```
最終的には以下のようなコードになります。
```Clojure
(def A (read))
(def P (read))
(def triple-a (* A 3))
(def all-pieces (+ triple-a P))
(def ans (quot all-pieces 2))
(println ans)
```
やろうと思えばもっと簡潔なコードにすることもできますが、どういうコードを提出したは見られず正しい値を出力することのできるコードのみが機械的に評価されるのでこのままでも全く問題ありません。

このコードを実際に提出してみた結果が以下のとおりです。
![Screenshot 2024-08-04 at 18.32.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494341/9c0ba351-1db4-6cf4-f696-e932cbc41b73.png)
無事にすべてのテストケースでAC(Accepted)となりました。（ステータスに関しては[こちら](https://atcoder.jp/contests/abc074/glossary?lang=ja)をご参照ください。）

以上がClojureで競技プログラミングに参加する基本中の基本です。
競技プログラミングは新しい言語に慣れるためには非常に効率的な手段だと思っています。
入力値をどう受け取るかということとどう出力するかということがクリアできればあとはロジックを考えて実装するだけなので、ぜひ気軽にClojureで参加してみてください。
Power Automate for desktop の Picture-in-Picture でエラーが出る時の対処法

こんにちわ、 [のりじ](https://x.com/nori790822) です。

デスクトップフロー（Power Automate for desktop）の実行方法に「Picture-in-Picture」を選択できるようになっています。

## 1. Picture-in-Picture とは

![202407-01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103396/7c3c386b-f3ec-6273-f0d8-67f979f66f5a.jpeg)

Picture-in-Pictureは、デスクトップを複製する仮想ウィンドウ内でフローを実行する機能です。
この機能を活用すると、PADを実行する時にユーザーは作業を止める必要が無くなります。

## 2. 個人PCで「Picture-in-Picture」が実行できない・・・

とても便利な機能なのですが、個人PCでクラウドフローからデスクトップフローを「Picture-in-Picture」でフロー実行させようとしたらうまくいかず、以下のエラーが出ました。

![001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103396/1c807006-30b9-61c3-59ef-7645addf8d95.jpeg)

これを解消するのに結構ハマってしまったので、方法を記載しておきます。

:::note info
公式ドキュメント
[Picture-in-Picture でデスクトップ フローを実行する (プレビュー)](https://learn.microsoft.com/ja-jp/power-automate/desktop-flows/run-desktop-flows-pip)
:::

## 3. 「Picture-in-Picture」利用時の前提条件

「Picture-in-Picture」を利用したい場合、以下の条件が必須になります。

- デスクトップ用 Power Automateが、使用しているマシンにインストールされている
- Power Automateを使用するには、ユーザーがサインインしている必要がある
- ユーザーは、従量課金環境へのアクセスか、Power Automate Premiumプランが必要

また今回、エラーが出た私のPCやライセンスは以下の内容でした。

- 個人PCである
    - 管理権限などすべて触れる状況 
    - ローカルアカウントを利用
    - PC起動時、Windows HelloのPIN認証ではなくパスワードを利用
- 環境は「既定の環境」を利用
- PADのバージョンは「2.45」
- Windowsのバージョンは「Windows11 pro」
- Power Automate Premiumプランあり

## 4. グループポリシーの設定

「フローが実行できません」のエラーが表示された場合、Windowsの「グループポリシーの設定」を見直すことでエラーが解消される場合があります。（自分のPCはコレだった）
以下、設定方法を記載します。

:::note warn
社用PCなど管理されているPCの場合は、個人判断せず社内のルールや管理者の指示に従ってください。
:::

コントロールパネルを開きます。

![pad01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103396/7b55d509-de4b-3848-3b93-5273bbfcb57b.jpeg)

検索窓に「グループ」と入力して検索し、「グループポリシーの編集」をクリック。

![pad02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103396/f18b0e42-065b-b403-3c45-646aef2a542c.jpeg)

「ローカル グループ ポリシー エディター」が開くので「コンピューターの構成」をクリック。

![pad03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103396/8dcc84f9-a211-a92b-52cb-f910a3bb9453.jpeg)

「管理用テンプレート」をクリック。

![pad04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103396/df518f1d-365b-2480-f33b-e281bbdb9816.jpeg)

「システム」をクリック。

![pad05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103396/17dd7749-dfbb-8f82-c705-8a5f2c4fbda1.jpeg)

下の方にスクロールすると表示される「資格情報の委任」をクリック。

![pad06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103396/4ce4edfa-5b34-6470-be85-b153622f783d.jpeg)

「既定の資格情報の委任を許可する」をクリック。



「値」に以下の内容を入力。

```
TERMSRV/*
```
最後に「適用」ボタン⇒「OK」ボタンをクリック。
「グループポリシーの設定」が完了しました。

PCを再起動後、デスクトップフローの実行方法で「Picture-in-Picture」を選択するとエラーが出ずに実行できようになります。

## さいごに

現時点では「プレビュー」の機能なので今後設定など変わってくるかもしれませんが、現時点ではこの方法で対応できました。
エラー解消方法の一つということで読んでいただければ！
【Jest】Unable to find an element with the text: 〜〜〜 というエラーの対処

# はじめに
react-hook-formを利用して0以下の数値を入力した際にバリデーションエラーが出ることのテストを実装してる際に以下のエラーが出たのでその対処法を書く。

# 問題
以下のエラーが出る。
```
Unable to find an element with the text: ⚠️学習時間は1以上である必要があります。
```
問題のコード↓
```js
 test('学習時間が1以上でないときに登録するとエラーが出る', async () => {
    // 学習記録を登録するためのモーダルを開く
    const registerButton = screen.getByTestId('add-record-button');
    userEvent.click(registerButton);
  
    // 学習時間を入力せずに送信ボタンをクリック
    await waitFor(() => {
      const submitButton = screen.getByTestId('submit-button');
      userEvent.click(submitButton);
    });
  
    // 学習時間は必須項目のエラーメッセージが表示されていることを確認
    await waitFor(() => {
      expect(screen.getByText('⚠️学習時間は必須入力項目です。')).toBeInTheDocument();
    });
  
    // 学習時間を入力する
    const timeInput = screen.getByTestId('time-input');
    userEvent.clear(timeInput);
    userEvent.type(timeInput, '-1'); // 0以下の値を入力することでエラーが発生することを確認
  
    // 再度送信ボタンをクリック
    userEvent.click(screen.getByTestId('submit-button'));
  
    // 学習時間が1以上である旨のエラーメッセージが表示されていることを確認
    await waitFor(() => {
      expect(screen.getByText('⚠️学習時間は1以上である必要があります。')).toBeInTheDocument();
    });
  });
```
コンソールログで確認してみたところ、-1を入力しているにもかかわらず'⚠️学習時間は必須入力項目です。'のままで'⚠️学習時間は1以上である必要があります。'が出力されていないためテストがエラーになっています。

# 原因 & 解決策
現状だと入力をする箇所で入力が終わる前にsubmit-buttonが押されてしまうため、適切なエラーメッセージが表示されません。なのでしっかり入力が終わるまで待ってあげる必要がありました。
```diff_javascript
   // 学習時間を入力する
    const timeInput = screen.getByTestId('time-input');
    userEvent.clear(timeInput);
-   userEvent.type(timeInput, '-1'); // 0以下の値を入力することでエラーが発生することを確認
+   await userEvent.type(timeInput, '-1'); // 0以下の値を入力することでエラーが発生することを確認
```
これでテストが正常に動作するはずです。~~初心者エラーな気がしますが1時間くらい解決に時間かかりました。~~
<details><summary>テストコード全体</summary>

```js
  test("学習時間が1以上でないときに登録するとエラー", async () => {
    const registerButton = screen.getByTestId("add-record-button");
    userEvent.click(registerButton);

    await waitFor(() => {
      const submitButton = screen.getByTestId("submit-button");
      userEvent.click(submitButton);
    });

    await waitFor(() => {
      expect(
        screen.getByText("⚠️学習時間は必須入力項目です。")
      ).toBeInTheDocument();
    });

    const timeInput = screen.getByTestId("time-input");
    userEvent.clear(timeInput);
    await userEvent.type(timeInput, "-1");
    userEvent.click(screen.getByTestId("submit-button"));

    await waitFor(() => {
      expect(
        screen.getByText("⚠️学習時間は1以上である必要があります。")
      ).toBeInTheDocument();
    });
  });
```

</details>

# おわりに
どのタイミングで処理が完了されるまで待ってあげる必要があるのかなんとなくわかってきました。あと今回のエラーとは関係ないですがテストを意識してApp.tsxなどのメインロジックを書く方が良いとなんとなく思いました。より良いコードを書いていけるよう精進していきたいです。
PowerAppsでローコード開発する際に関連になりそうなWEBサイトリンク

## 背景
とある時にPowerAppsでローコード開発を行う機会があった。
関連しそうなWEBサイトリンクを調べたので整理

## ポイント
- ローコード開発対象と類似の記事を発掘できるかどうか
- イメージするデザインテンプレートを見つけられるかどうか

## WEBサイトリンク

ボタンを押すたびにカウントアップする

https://www.youtube.com/watch?v=JibEAJPj52Y

しんけいすいじゃく

https://island3m.hatenablog.com/entry/2021/09/01/

https://hanakuso365.hatenablog.com/entry/2022/03/09/113000

# 参考

https://www.youtube.com/watch?v=JibEAJPj52Y

https://qiita.com/mocca1103/items/42e1639d5213f42504f1
CloudflareでデプロイしたAPIとFlutterでAPI通信する

## はじめに
表題通り、CloudFlareでデプロイしたAPIとFlutterをAPI通信させます。

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/facd4c2d-5769-2416-3b15-fb98197075aa.png">

## プロジェクト作成
### API（Cloudflare）のプロジェクト作成
```shell
~/develop/cloudflare_api (HEAD)$ npm create cloudflare@latest
```

```toml:wrangler.toml
#:schema node_modules/wrangler/config-schema.json
name = "flutterflaresample"
main = "src/index.ts"
compatibility_date = "2024-07-29"
account_id = "XXXXXXXXXXXX"
workers_dev = true

[dev]
port = 8787
```

```ts:index.ts
import { Hono } from 'hono'

const app = new Hono()

app.get('/', (c) => {
  return c.json({ message: 'Hello from Hono on Cloudflare Workers!' })
})

export default app
```

### Flutterのプロジェクト作成

```shell
flutter create my_app
```

```dart:
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('API Communication Example'),
        ),
        body: Center(
          child: ApiDemo(),
        ),
      ),
    );
  }
}

class ApiDemo extends StatefulWidget {
  @override
  _ApiDemoState createState() => _ApiDemoState();
}

class _ApiDemoState extends State<ApiDemo> {
  String data = '';

  void fetchData() async {
    final response = await http.get(Uri.parse(
        'https://XXXXX.workers.dev'));

    if (response.statusCode == 200) {
      setState(() {
        data = json.decode(response.body)['message'];
      });
    } else {
      setState(() {
        data = 'Failed to load data';
      });
    }
  }

  @override
  void initState() {
    super.initState();
    fetchData();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text(data),
        ElevatedButton(
          onPressed: fetchData,
          child: Text('Fetch Data'),
        ),
      ],
    );
  }
}

```

## 実行
flutter runで実行。
APIサーバから取得した値が表示されるようになります。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/facd4c2d-5769-2416-3b15-fb98197075aa.png">
yukicoder No.71 そろばん　解説

[問題文](https://yukicoder.me/problems/no/71)

# 解説
まず、仮に上の珠の数を $u$ 、下の珠の数を $d$ とする。
下の位は $0,1,2,...,d-1,d$ が表せる。
上の位は $0,(d+1),2(d+1),...,(u-1)(d+1),u(d+1)$ を表せる。
つまり、表せる数の最大値は $u(d+1)+d$ となる。
続いて、珠の合計数が $N$ だと $u+d=N$ という式が成り立つ。 $N<=10^6$ なので、ありえる $u$ と $d$ の組み合わせを全探索しても今回は間に合う。
実行時間は$O(N)$。
$N$ が大きいとオーバーフローするのでlong long型を使うこと。

# C++での解答例
```C++
#include <bits/stdc++.h>
using namespace std;
using ll=long long;

int main(){
  ll n,ans=0;cin>>n;
  for(ll u=1;u<n;u++){
    ll d=n-u;
    ans=max(ans,u*(d+1)+d);
  }
  cout<<ans<<endl;
}
```
ブランチを再利用してPRを作成する是非

## 質問
GitHubのPR１はmasterからブランチ１を切った差分として表示されます。
PR１がマージされたとして、例外的にブランチ１に戻り、修正事項を追加して、PR２を作成してPRを作成したとして、PR１とPR２では内容はちがう認識でいますが、PR１の`FileChanges`はPR１を作った時のブランチ１の差分として表示されるのか、
それともPR２を作った時のブランチとして、PR１のFileChangesとして反映されるのかどちらでしょうか？

## GPT4o回答

GitHubのプルリクエスト（PR）は、それぞれ特定のブランチの特定の状態を対象としています。以下のように考えることができます：

1. **PR1の状況**:  
   - ブランチ `branch1` を `master` から作成し、いくつかの変更を加えてPR1を作成しました。
   - PR1のFile Changesは、PR1が作成された時点での `branch1` の差分を表示します。

2. **PR1のマージ後に `branch1` に修正を追加**:
   - PR1がマージされた後に、 `branch1` に戻って新たな修正を行います。
   - この時点で `branch1` の状態は、PR1のマージ後の状態から変更された新しいものになります。

3. **PR2の作成**:
   - `branch1` に新たな変更を加えた後、その変更を基にPR2を作成します。
   - PR2のFile Changesには、PR2が作成された時点での `branch1` の変更内容が表示されます。

**重要なポイント**: PR1のFile Changesは、PR1が作成された時点の差分で固定されています。したがって、PR1がマージされた後に `branch1` に変更を加えても、PR1のFile Changesには反映されません。PR2は新たに作成されたPRとして、PR1とは異なる内容の差分が表示されます。つまり、PR1とPR2のFile ChangesはそれぞれのPRが作成された時点の `branch1` の差分を反映しています。

結論として、PR1のFile ChangesはPR1作成時の `branch1` の差分として表示され、PR2作成後の変更はPR2のFile Changesにのみ表示されます。

## 追加質問
ということはブランチを再利用してPRを作成する分には、PR１は記録されるので問題なさそうですね。

## GPT4o回答
はい、その通りです。ブランチを再利用して新たなPRを作成する際には、各PRが作成された時点でのブランチの差分がそれぞれ記録されるため、PR1とPR2の内容は独立して扱われます。

ブランチを再利用する場合も、各PRは別々の変更を記録するので、問題なく使い続けることができます。ただし、コードベースの管理やチームでの協力の観点から、明確な変更履歴を保つために新しい機能や修正ごとに新しいブランチを作成することが一般的に推奨されます。それにより、変更の追跡やコードレビューがより容易になります。
yukicoder No.70 睡眠の重要性！　解説

[問題文](https://yukicoder.me/problems/no/70)
# 解説
まず、今回の問題は出力形式が特殊になっている。
こういう時は**scanf**を使うといいだろう。
scanf("%d:%d %d:%d",&H,&M,&h,&m)と書けばよい。
次に睡眠時間のためだが、求めやすさのため分に直して求める。
どういうことかというと、ある変数$T$を$H\times 60+M$として求めるということだ。
これで$T=H\times 60+M$、$t=H\times 60+m$として求める。
で、これからどうやって睡眠した時間を数えるかというと、
・$T\leqq t$→$t-T$
・$T>t$→$t-T+1440$
これをそれぞれ求めて、最後にその総和を求めれば終わり。
# C++での解答例
```C++
#include <bits/stdc++.h>
using namespace std;

int main(){
  int n,sum=0;cin>>n;
  for(int i=0;i<n;i++){
    int H,M,h,m;
    scanf("%d:%d %d:%d",&H,&M,&h,&m);
    getchar();
    int T=H*60+M,t=h*60+m;
    if(T<=t)sum+=t-T;
    else sum+=t-T+1440;
  }
  cout<<sum<<endl;
}
```
【技術書紹介】vol.1 : 良いコード/悪いコードで学ぶ設計入門 ―保守しやすい 成長し続けるコードの書き方

こちらの書籍を読んで非常に面白かったので他の方にもおすすめしたくなり、読みたくなるような記事を書ければと思いました。簡単に紹介いたします。

# info
- 書籍名 : 良いコード/悪いコードで学ぶ設計入門 ―保守しやすい 成長し続けるコードの書き方
- 著者 : 仙塲大也 様

https://www.kinokuniya.co.jp/f/dsg-01-9784297127831

# 本書の特徴
- 可読性が高くバグの出にくいコードの書き方が載っています
- コードはJava言語で書かれていますが、他言語の経験さえあれば理解できます
- 親しみやすく面白い技術書ですが、出てくる用語が相手に伝わる一般用語なのか判別が必要です

# 内容の感想
### すぐに取り組めそうなこと
1. **if文のネスト**
if文で条件が2重・3重にもネストしていたり、elseifで延々と条件が繋がっていると処理を追うのが負担になる。`早期リターン`ですぐ返してあげるとよい。
2. **NULL問題**
「無」の状態を表現するために安易にNULLを使うと至る箇所でNULLチェックが必要になる上、実装漏れが命取りに。「`0`」や「`""`」のプリミティブ型を使うことを意識するとよい。
3. **マジックナンバー**
コード上に突如「4」といった数値が現れるとその数値が何を意味しているのか分からない。`メンバ変数`にして数値に意味を持たせるとよい。配列の添え字にも同様に気を付けたい。

### 本腰入れれば取り組めそうなこと
1. **interfaceの利用**
安易にswitch文やif文で分岐処理を実装してしまうとコードの重複や実装漏れにつながる。まずは`interface`や`その実装クラス`を作ることを検討してみる。
2. **名前設計**
例えばクラスを「商品コントローラー」という単位で作ってしまうと、「仕入商品」・「配送商品」・「注文商品」...といった全ての商品に関連する処理が集まってしまうので、`特化した名前`を付けると実装箇所が分散されてコードが見やすくなる。（他にも`技術駆動命名`など面白い視点があった。）

# おわり
ここにはとても書ききれませんが、他にも有益な情報がたくさんありました。
半年ほど空けて2周目読みましたが、まだ身についてないことも多いのでまた忘れたころに繰り返し読もうと思います。
Microsoft Graph API を使うための、Azureの設定方法 ~デスクトップアプリ開発~

## 1. はじめに
[Microsfoft Graph Api](https://learn.microsoft.com/ja-jp/graph/api/overview?view=graph-rest-1.0&preserve-view=true)を使用すると、ファイルをダウンロードしたり、アップロードをしたり、ユーザーの情報を取得したりと様々なことが可能になります。  
本記事では、Microsoft Graph Api を使用して開発を始める前に必要な準備についてご説明していきます。  

※本記事はC#のデスクトップアプリケーションの開発を想定しておりますが、それ以外の開発でも設定は同じような流れで実施できると思います。

## 2. Azure のアプリ登録の方法
Microsfoft Graph Apiを使用するには、あらかじめ、Azureでアプリの登録を行っておく必要があります。  

※Azure を始めたことのない方は、[こちら](https://azure.microsoft.com/ja-jp/free/)からAzureの公式ページにアクセスし、「無料で始める」をクリックし、ログインしてください。  
Microsoftのアカウントがあれば、実施可能です。  

### 2.1. Azureへのログイン

① Microsoft 365 管理センター に Microsoft アカウントでログインする。  
② サイドナビから [Azure Active Directory]をクリックする。  
③ 遷移後の画面のサイドナビから [Azure Active Directory]をクリックする。 

![2024-08-04_16h44_49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3131319/96d80006-7b2b-6c29-ebe7-ed82b8170123.png)

※[こちら](https://portal.azure.com/#home)からでもAzureにMicrosoftアカウントでログインできます。

### 2.2. アプリケーションの登録

① [管理]→[アプリの登録]を選択し、[新規登録]をクリックする。  

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3131319/1670fe52-2623-8b7b-5ab3-2d34c3385db5.png)

② アプリケーションの登録情報を入力。  

![2024-08-04_16h49_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3131319/e26e89f8-59ec-14bc-54a0-47f851ce1e3f.png)

### 2.3. Microsoft Graph ApiのAPIのアクセス許可を選択して登録

① [APIのアクセス許可]を選択し、[アクセス許可の追加]をクリックする。  ![2024-08-04_16h55_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3131319/0eb192ad-8579-0aa2-ebb9-63c0ad08795e.png)

② [Microsoft API]タブで下にスクロールし、[Microsoft Graph]を選択。  
![2024-08-04_16h56_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3131319/397fab5a-58fc-cd51-5275-a4663aa37102.png)

### 2.4. APIの選択  

例えば、ファイルの読み取り処理の権限を付与したい場合は、以下のように Files.Read を選択。  

![2024-08-04_17h13_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3131319/006074cc-9183-809a-2631-05e0d6fbc296.png)

実際に使用するAPIに必要なアクセス許可を選択するようにします。  
後は、同意をクリックすれば、完了です。  
ただ、デスクトップアプリケーションの開発で使用したい場合は、次章の設定もしておきましょう。  

### 2.5. デスクトップアプリ開発に必要なリダイレクトURLの設定

2.4章の完了後、アプリ登録済みのアプリに、リダイレクトURLを追加します。  


① [概要]→[リダイレクトURIを追加する]をクリックする。
![2024-08-04_17h26_44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3131319/8a6a1226-8327-55de-da73-02ce97df99b1.png)

② 「プラットフォームの追加」⇒「プラットフォームの構成」から
モバイルアプリケーションとデスクトップアプリケーション」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3131319/4d285f97-0530-2773-12da-73ee35201df5.png)

③ 「デスクトップとデバイスの構成」にて任意のリダイレクトURLを設定。  
詳しくは[こちら](https://learn.microsoft.com/ja-jp/entra/identity-platform/scenario-desktop-app-registration#redirect-uris)を参照してください。


## 3.　おわり

今回はここまでです。
次回からは、実際に、C#の開発でMicrosoft Graph API を使用して、ファイルのダウンロードやアップロードを題材に、さまざまなAPI呼び出しを紹介します。 
詳細はそちらの記事を参照ください。
【React】useRefを理解する

# 本記事の目的

- React Hooksの`useRef`とは何かを理解する
- `useRef`の使い道を理解する

# まずは結論

`useRef`とは、「**値の更新による再レンダリングが実行"されない"値を定義できるヤツ**」です。

実際に格納されている値には`current`プロパティを介してアクセスします。

```react
const myRef = useRef<number>(1);

console.log(myRef.current); // 1
```


# 詳しく解説


通常、`useState`を使って状態を管理すると、その状態が変更されるたびにコンポーネントが再レンダリングされます。

それに対して`useRef`は、値が更新されてもコンポーネントの再レンダリングを実行しないという特徴があります。頻繁に更新される値や、再レンダリングを引き起こすことなく参照を保持したい場合に使われます。


### 特定のDOM要素への『参照』を保持する

`useRef`はDOM要素への参照を保持する際によく利用されます。

例えば、要素にフォーカスを当てる、スクロール位置を調整する、要素のサイズを取得するなどの操作はDOM要素への参照を通して行う必要があります。

プレーンなJavaScriptでDOM要素を参照する際には、`document.getElementById`等のメソッドを使用しますが、Reactでは`useRef`を使用します。


以下の例では、`useRef<HTMLInputElement | null>(null)`で作成した`inputRef`を、テキストフォームの`ref`に指定することで、`inputRef`を通してテキストフォームのDOM要素へ直接アクセスできるようにしています。
そして初期処理の中で`focus`メソッドを実行することで、`inputRef`と関連付いたテキストフォームをフォーカス状態にしています。
```react
export const HelloWorld: React.FC = () => {
  const [name, setName] = useState<string>("");
  const inputRef = useRef<HTMLInputElement | null>(null); // Refを作成

  useEffect(() => {
    inputRef.current?.focus(); // フォーカスを当てる
  }, []);

  return (
    <>
      <input
        type="text"
        placeholder="Enter your name"
        ref={inputRef} // inputRefとの関連付けをする
        value={name}
        onChange={(e) => setName(e.target.value)}
      />
    </>
  );
};
```
useStateの値を更新したのに古い値が表示される

# はじめに
ReactのuseStateを使用した際の処理で引っかかった点があったのでまとめてみようと思います。

# 事象
以下のようなbuttonがクリックされたら配列の中身を表示する処理があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/999bb389-f609-85e0-d20d-ec90676ea918.png)
```jsx:App.jsx
const [array, setArray] = useState([]);
const [element, setElement] = useState(0);
const onChangeElement = (event) => setElement(event.target.value);
const onClickButton = () => {
  setElement(element);
  const newArray = [...array, element];
  setArray(newArray);
  setElement(0);
  console.log(array);
}

return (
  <>
    <div>
      <input type={"number"} value={element} onChange={onChangeElement} />
    </div>
    <button onClick={onClickButton}>表示</button>
    <p>={JSON.stringify(array)}</p>
  </>
)
```

1,2,3と入力とそれぞれ入力していけば配列に値が追加されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/fee88a81-adf1-48b3-5aee-2965ba50856f.png)

ここで、`console.log(array)`の部分は`setArray(newArray);`で新しい配列に置き換えているので、新しい配列がconsole.logに表示されると思っていました。
しかし、表示されたのは3を追加する前の古い配列でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/9cd53fb5-06b5-ad81-e342-a351b8e3128e.png)

以下のように実行しても、同じ結果です。
別の関数`consoleLogsShow`で`console.log(array);`を実行
```jsx
const [array, setArray] = useState([]);
const [element, setElement] = useState(0);
const onChangeElement = (event) => setElement(event.target.value);
const onClickButton = () => {
  setElement(element);
  const newArray = [...array, element];
  setArray(newArray);
  setElement(0);
  consoleLogsShow();
}

const consoleLogsShow = () => {
  console.log(array);
} 
```

# 原因
~~useStateは非同期に処理を行うため、`onClickButton`の関数で`console.log(array);`を行った段階では更新されていないようでした。~~

gptに聞いてみたら
>これは React の状態管理に関する一般的な問題です。console.log の値が変更する前のものになっている理由は、React の useState フックが非同期で動作するためです。setArray や setElement を呼び出しても、その後すぐに console.log で状態を確認すると、まだ更新されていない古い値が表示されることがあります。

ということでした。

<font color="red">追記：上記の情報は間違いみたいでした。
setXX 関数がこの挙動の原因ではないようです。
js の関数のスコープの仕組みを使っているので、onClickButton の内側では、array 変数の中身はタイミングによらず必ず古い値となるみたいです。
</font>

<font color="red">コメントくださった方ありがとうございます！</font>

以下、参考

https://qiita.com/honey32/items/ee8d1577e68b0d58678d

# 解決策
- 新しい配列のnewArrayを使うようにする
これだと古い情報は表示されなくなりますね。
```jsx
const onClickButton = () => {
  setElement(element);
  const newArray = [...array, element];
  setArray(newArray);
  setElement(0);
  console.log(newArray);
}
```
- useEffectを使用する
arrayが変更されたら処理を実行してくれます。
```jsx
const onClickButton = () => {
  setElement(element);
  const newArray = [...array, element];
  setArray(newArray);
  setElement(0);
}

useEffect( () => {
  console.log(array)
}, [array])
```

# 終わりに
関数内でuseStateの値を使い、別の処理を実行したい場合は注意していきたいと思います。
React初心者が学習記録アプリを開発！

# はじめに
Reactを学び始めて、まだ1週間立っていませんが学習記録アプリを開発しました。
学習した内容と時間を記録できる簡単なアプリです。
今回は開発したアプリの内容や感想を伝えたいと思います。

# 開発したアプリ
学習内容と時間を記録できる学習記録アプリを開発しました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/16522ddc-62ea-408a-c2da-9f091b917cb0.png)

簡単にですが、機能を説明していこうと思います。
- 入力している内容が学習内容と入力されている時間に表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/5175473f-f85a-b60d-39b8-0f7d420acc94.png)
- 学習内容と学習時間を入力し、登録できる
- 合計時間が下部に表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/7447f368-1e75-9239-69d7-08a336c39c33.png)
- 学習内容または学習時間が空の場合はエラーが出る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/92788470-a501-1f96-a281-062245d5bd99.png)

# 0→1になるまで
Reactはまったく知らないという状態でしたが、まずはudemyの動画を視聴して、Reactの基礎を学びました。
順を追ってステップアップしていき、ReactのTODOアプリ作成から今回の学習記録アプリ開発しました。

<font color="red">知らない状態からReactの基礎が分かる、そして簡単なアプリを作成できる状態までに成長できました。</font>

# 大変だった点や工夫した点
React独自の`useState`や`useEffect`という関数があるのですが、どの言語でもありますがやはり最初は使い方に慣れなくてとまどう部分がありました。

慣れるためには、何度か復習したり、実際に手を動かして使ってみたりしました。
また、udemyで基礎を学んでいく中で、処理のコンポーネント化（特定の部分を部品にして使いまわせるようにする）することも試してみました。

（実はこの部分、コンポーネント化してます）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/f4c83e8a-9356-ebb0-18e5-9b3997046684.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/e8ebedbc-9364-e846-36b9-e16a90497a7d.png)


# 初学者だからこそ大切にしたいこと
やはり、初めて学ぶものは基礎を学んでから実際に開発を行うということが大切です。
なんとなく、Reactやってみたいから学習記録アプリ作ってみようだといろんなところで躓いていたと思います。

しっかりと基礎から学び、アプリ開発に手を出すという順序だてながら行えたのは良かったと思います。


# これからReact始めたい方へ
Reactを学んでいくうえで大切なのは、正しい学習順序を知ってそれを遂行することだと思います。
初っ端から自分の実力を見誤ると、どの言語の学習でも挫折します、、

React始めて約1週間立ちましたが、約1週間前のReactわからない自分と今を比べて少し達成感というか自信がつきました。
少しだけ、自分が誇らしいです！

# 終わりに
さらにReact学んでいきたいと思います。昨日より、先に進んでいきます。

# JISOUのメンバー募集中
プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？

気になる方はぜひHPからライン登録お願いします👇

https://projisou.jp
Formタグと@method

初学者向けの内容。不明点をまとめた。

## 環境
OS: Windows11 バージョン23H2
Laravel: 9.52.16
PHP: 8.1.0
開発環境:MAMP

## Formタグのこと
```php:商品一覧のView

      <form action="{{route('list')}}" method="get">
            @csrf
        <div>
            <h2>商品一覧画面</h2>
            <div class="search">
                <input type="search" name="search" class="formCont" placeholder="検索キーワード" value="{{ request('search') }}">
                <input type="search" name="maker" class="formCont" placeholder="メーカー名" value="{{ request('maker') }}">
                <input type="submit" name="submit" class="kensaku" value="検索" onclick="location.href='http://localhost:80/laravel7/public/list'">
            </div>
        </div>
      </form>

----------------------------------------------------------------------------------

        <form action="{{ route('list_delete', $product->id) }}" method="POST">
                @csrf
                @method('DELETE')
            <button class="delete" type="submit">削除</button>
        </form>

```
検索ボタン、削除ボタンを書く際にFormタグを使っている。少し前まではFormタグでどこからどこまでを囲めばいいのかよくわかっていなかった。
今はデータベースまで動作が及ぶようなボタンを実装したいときに「@csrf+button」をFormで囲めばいいんだなと解釈している。

そこでFormをFormで入れ子状態にしたらどうなるのか疑問に思ったので調べてみた。

## 結論
**HTML公式「Formタグの入れ子はやめれ」**
参照：https://developer.mozilla.org/ja/docs/Web/HTML/Element/form


とのことだった。
ほか、Qiitaの記事も参考にしたものがあるのでのせる。
基本的にしてはいけないが、下記のように方法はある感じだった。
→https://qiita.com/k5trismegistus/items/eda92664037f96f40e37

Formタグを入れ子にせず複数使用するのはとくに問題ない。

## 「@method('DELETE')」ってなに
・@methodとは
bladeディレクティブ（@if,@sectionなど）の一つ。GET・POST以外のHTTPメソッドを利用したいときに@methodを使う。

・('DELETE')とは
HTTPメソッドの一つ。GET/POST/DELETEのほかにPUTなどがある。
Formタグのmethod属性に対してはGET/POSTしか指定することができないため、このようにディレクティブとあわせて利用する。


### ◎具体的な使い方

```php:例

<form action="/sample/index" method="patch">
   <input type="submit" text="提出">
</form>
```

上記のように入力するとエラーが出てしまう。理由は前述したとおりで、「method="patch"」の部分にある。
Formタグのmethod属性にはGET・POSTしか対応していないため、それ以外の値を入れたとしても実際にはGET・POSTでしか動かない。

```PHP:修正ver
<form action="/sample/index" method="post">
@csrf
@method('patch')
   <input type="submit" text="提出">
</form>
```
例文にはsubmitとあるので、Formタグのmehod属性はpostにする。
「@method('patch')」と指定することでエラーも起きず通信することができる。


### ◎仕組みについて
→@method('patch')の部分は実際には下記のように変換される。
```PHP:@method('patch')を変換すると
<input type="hidden" name="_method" value="patch">
```
サーバー側はvalueの部分をみてルーティングをする。
というような仕組みになっている。


## 最後に
よくわかってなかった部分を少しまとめただけ。
「事実よりも形式」が重視されるときはRAGよりもファインチューニングが有効

## はじめに

LLMに新しい情報を与える方法の代表例として、RAG(Retrieval-Augmented Generation、検索拡張生成)とファインチューニングがあります。

この記事では、「**RAGよりもファインチューニングが効果的**」となる状況を具体例とともに説明します。

この記事は、RAG、ファインチューニング、プロンプトエンジニアリングの基礎知識をお持ちの方向けです。ただし、これらの用語に馴染みがない方も、理解を深められるように引用先を示します。

## 先に結論

タスクに特化したいとき、特に**事実よりも形式**が重視されるときは、RAGよりもファインチューニングが有効と考えられます。

## 事実と形式
「事実」は辞書通りの意味でファクトです。「形式」は、「らしさ」や「出力形式」です。

例えば、FAQに基づくチャットボットで正確な情報提供が求められる場合は「事実」が重要です。一方で、回答における性格の一貫性を保ちたい場合は「形式」を重視といえます。

RAGとファインチューニングはその特性から得意領域が異なります。RAGよりもファインチューニングがより有効と考えられる「形式」を重視する例を紹介します。

## 例①話し方の出力

「話し方」を学習させるにはファインチューニングが有効となり得ます。

例えば、語尾を変えるなどです。次の記事では、語尾を「ござる」に変えるキャラ付けファインチューニングを実験しています。さらにプロンプトエンジニアリングとの比較があります。

結果として、特に軽量のLLMにおいてファインチューニングが有効となり得ることが示唆されています。

> ChatGPTのような大規模で高性能なLLMについてはプロンプトエンジニアリングで比較的簡単にキャラ付けができることはよく知られていますが、より小さいLLMにおいては、プロンプトエンジニアリングによるキャラ付けは安定せず、ファインチューニングのほうが効果的であるのではないかと考えられます。

https://note.com/sharp_engineer/n/ne9c667a01d0e

## 例②絵文字の出力

絵文字の出力に特化したタスク（絵文字分類タスク）を解く際にもファインチューニングが有効となり得ます。

絵文字の出力タスクは、LLMに新たな知識（絵文字）を加えるだけでなく、「絵文字の出力」という出力方法に焦点が当たります。

次の記事では、ファインチューニングによって精度を向上した事例が紹介されています。

https://note.com/nyosubro/n/naf302a45b152

## 例③書き下し文の出力

次の記事は白文から書き下し文を出力する例です。

書き下し文の出力も、LLMに新たな知識を加えるだけでなく、出力方法に焦点が当たります。

https://miraitranslate-tech.hatenablog.jp/entry/20231201-llm-kambun

## 例④専門用語の出力

出力される用語を専門用語にすることも「形式」を重視するといえます。

例えば、金融領域です。金融領域には金融で使われる専門用語があります。
金融業界で使用されるLLMが、金融の専門用語を用いて回答されるとLLMの価値が上がります。

例えば、次のような論文では、金融ドメイン特化のためのLLMのインストラクションチューニング（ファインチューニング手法の一つ）について議論されています。

[「金融ドメイン特化のための大規模言語モデルのインストラクションチューニング評価」](https://www.jstage.jst.go.jp/article/pjsai/JSAI2024/0/JSAI2024_3Xin253/_pdf/-char/en)

["FinGPT: Instruction Tuning Benchmark for Open-Source Large Language Models in Financial Datasets"](https://arxiv.org/abs/2310.04793)

## おわりに

この記事では、事実よりも形式が重視されるときは、RAGよりもファインチューニングが有効と考えられること、ファインチューニングが有効に働く事例を紹介しました。

RAGやファインチューニングを考える際の参考になれば幸いです。

## 参考

https://www.nri.com/jp/knowledge/glossary/lst/alphabet/rag

https://leapwell.co.jp/tech_column/blog-finetuning-vs-rag#3.RAG_FineTuning

https://www.anyscale.com/blog/fine-tuning-is-for-form-not-facts?ref=blog.langchain.dev

https://note.com/npaka/n/nec63c01f7ee8

https://qiita.com/DeepMata/items/05221c2914d1cfbf32ee
【MySQL】副問合せで、LIMITが使用できない

## はじめに

MySQLで「視聴ランキング3位までの番組タイトル名を出力せよ」という課題が出た。

副問合せの中で、ORDER BY句とLIMIT句を使い、
ランキングの上位3位を取得しようとしたが、以下エラーになったので、その対処法を記す。

```sql
mysql> SELECT program_name
    -> FROM program
    -> WHERE program_code IN
    -> (SELECT program_code
    ->   FROM viewing_history
    ->  GROUP BY program_code
    ->  ORDER BY COUNT(*) DESC
    ->  LIMIT 3);
ERROR 1235 (42000): This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
```

#### 公式サイトの確認
本エラーについて、公式サイトで調べてみると、エラーメッセージの通りサポートされて
いないと記載があった。
https://dev.mysql.com/doc/refman/8.0/ja/subquery-errors.html

## 結論

外部にもう一つSELECTクエリを用意して囲ってあげることで、目的のデータを取得できた。

```diff_sql
SELECT program_name
  FROM program 
 WHERE program_code IN
+ (SELECT program_code FROM
 (SELECT program_code
  FROM viewing_history
  GROUP BY program_code
  ORDER BY COUNT(*) DESC
  LIMIT 3) 
+ AS popular_program);
```

### 解決方法
テーブル別名を付けてLIMITを付けた副問合せを入れ子にしてあげることで取得できるよう
になった。
その際、外のSELECTクエリに対してテーブル別名を付ける必要が出てくるので注意。
'ERROR 1248 (42000): Every derived table must have its own alias'のエラーが出ます。）

```sql
--エラーになったSQL
SELECT program_name
  FROM program
 WHERE program_code IN
 (SELECT program_code
   FROM viewing_history
  GROUP BY program_code
  ORDER BY COUNT(*) DESC
  LIMIT 3);
```
```diff_sql
--想定通りのデータを取得できた
SELECT program_name
FROM program 
WHERE program_code IN
+ (SELECT program_code FROM
(SELECT program_code
  FROM viewing_history
 GROUP BY program_code
 ORDER BY COUNT(*) DESC
 LIMIT 3) 
+ AS popular_program);
```

```sql
--実行結果
+--------------+
| program_name |
+--------------+
| News Program |
| Sports       |
| Comedy       |
+--------------+
```

## 実行環境および使用したテーブル

【動作環境】
- mysql  Ver 8.0.39-0ubuntu0.22.04.1 for Linux on x86_64 ((Ubuntu))

【使用するテーブル】

テーブル名：viewing_history（視聴履歴）
| viewing_history_id | program_code |
| ----- | ----- |
| 1 | 2 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 5 |
| 6 | 2 |
| 7 | 5 |
| 8 | 3 |
| 9 | 2 |
| 10 | 5 |

テーブル名: program（番組）
| program_code | program_name|
|-----|-----|
| 1 | News |
| 2 | Sports |
| 3 | Drama |
| 4 | Documentary |
| 5 | Comedy |

## 参考資料
https://dev.mysql.com/doc/refman/8.0/ja/subquery-errors.html

## まとめ
この方法により、LIMIT句が使えない場合でも行数を制限できました。
他にもよい方法があったら教えていただけますと幸いです。
IRISの進化した自動リリースノート生成機能：SourceSageとの統合で更なる効率化を実現

## はじめに

ソフトウェア開発プロジェクトにおいて、リリースノートは変更点を明確に伝え、プロジェクトの進捗を可視化する重要な役割を果たします。しかし、その作成プロセスは時間がかかり、人的ミスのリスクも伴います。IRISの自動リリースノート生成機能は、この課題に革新的なソリューションを提供します。

最新のアップデートでは、SourceSageとの統合により、リリースノート生成プロセスがさらに洗練され、効率化されました。この記事では、進化したIRISの自動リリースノート生成機能について詳しく解説します。

<blockquote class="twitter-tweet" data-media-max-width="800"><p lang="ja" dir="ltr">Releaseブランチをプルリクエストしてマージすると自動リリースノート作成モジュール改修。。。<br>リリースノートの生成物が微妙だったのでSourceSageのプロンプト生成機構のみを導入してリリースノートの生成したらめっちゃいい感じになった！！<br>これでいきます！… <a href="https://t.co/9neAVZS8D0">https://t.co/9neAVZS8D0</a> <a href="https://t.co/ExsgWH7h7Y">pic.twitter.com/ExsgWH7h7Y</a></p>&mdash; Maki@Sunwood AI Labs. (@hAru_mAki_ch) <a href="https://twitter.com/hAru_mAki_ch/status/1820008068291404033?ref_src=twsrc%5Etfw">August 4, 2024</a></blockquote> 

## 新しい自動リリースノート生成の仕組み

IRISの最新バージョンでは、以下のステップでリリースノートを生成します：

1. **トリガー**: プルリクエストがマージされると、自動的にリリースノート生成プロセスが開始されます。

2. **SourceSage実行**: 
   - 新旧タグの情報を使用してSourceSageを実行し、詳細な変更レポートを生成します。
   - `.iris.SourceSageignore`ファイルを使用して、分析対象外のファイルやディレクトリを指定できます。

3. **YAML設定更新**: 
   - `docs/.sourcesage_releasenotes_iris.yml`ファイルが自動的に更新され、最新のタグ情報が反映されます。
   - このYAMLファイルには、使用するAIモデルやリポジトリ情報などの設定が含まれています。

4. **プロンプト生成**: 
   - 更新されたYAML設定を使用して、SourceSageがリリースノート生成用の詳細なプロンプトを作成します。
   - このプロンプトには、変更の詳細な分析結果が含まれます。

5. **AI分析とリリースノート生成**: 
   - 生成されたプロンプトを使用して、AIモデル（例：Google Gemini AI）が高品質なリリースノートを生成します。

6. **GitHub Releaseの作成**: 
   - 生成されたリリースノートを使用して、新しいGitHub Releaseが自動的に作成されます。

## 主な特長と改善点

1. **SourceSageとの統合**: SourceSageを使用することで、より詳細で正確な変更分析が可能になりました。

2. **柔軟な設定**: YAML設定ファイルにより、リリースノート生成プロセスをプロジェクトのニーズに合わせて簡単にカスタマイズできます。

3. **インテリジェントな無視機能**: `.iris.SourceSageignore`ファイルを使用して、不要なファイルやディレクトリを分析から除外できます。

4. **自動化の強化**: タグ情報の取得から設定ファイルの更新、プロンプト生成まで、全プロセスが自動化されました。

5. **高度なコンテキスト理解**: 生成されるプロンプトには、プロジェクトの詳細な変更履歴が含まれるため、AIがより的確なリリースノートを作成できます。

## 設定方法

IRISの進化した自動リリースノート生成機能を有効にするには、以下の手順を実行します：

1. `.github/workflows/generate-release-notes.yml` ファイルをリポジトリに追加または更新します。

2. `docs/.sourcesage_releasenotes_iris.yml` ファイルをプロジェクトに追加し、必要に応じて初期設定を行います。

3. `.iris.SourceSageignore` ファイルを作成し、分析から除外したいファイルやディレクトリを指定します。

4. 必要なシークレット（`GITHUB_TOKEN`、`GEMINI_API_KEY`など）を設定します。

## 結論

IRISの進化した自動リリースノート生成機能は、SourceSageとの統合により、さらに強力で柔軟なツールとなりました。この機能を活用することで、開発チームは以下のメリットを享受できます：

- リリースノート作成にかかる時間と労力の大幅な削減
- 一貫性のある高品質なリリースノートの自動生成
- プロジェクトの変更履歴のより深い理解と可視化
- カスタマイズ可能な設定による柔軟な運用

IRISの自動リリースノート生成機能を導入することで、開発プロセスの効率化とプロジェクトの透明性向上を同時に実現できます。この革新的な機能を活用し、あなたのプロジェクトの情報発信をより効果的に、そして効率的に行いましょう。

<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
MatPlotClass and table


```python

import json
import pandas as pd
import openpyxl
import matplotlib.pyplot as plt
from matplotlib.ticker import ScalarFormatter, FormatStrFormatter
import japanize_matplotlib
from pathlib import Path
import pprint

class MatPlotLogX():
    def __init__(self):
        self.fig, self.ax = plt.subplots()
        
        # x軸とy軸を対数目盛りに設定する。
        self.ax.set_xscale("log")
        self.ax.set_yscale("log")

        # x, y軸のラベルを指数表記から通常の表記に設定(ただしe表記は残る)
        self.ax.xaxis.set_major_formatter(FormatStrFormatter('%g'))
        self.ax.yaxis.set_major_formatter(FormatStrFormatter('%g'))

        # X軸とY軸のラベルを設定
        self.ax.set_title("Acc result")
        self.ax.set_xlabel("frequency[Hz]")
        self.ax.set_ylabel("PSD")

        # グリッドを表示する。
        self.ax.grid(True, "major", linestyle="-", linewidth=.7, color='g')
        self.ax.grid(True, "minor", linestyle="-", linewidth=.3, color='g')

    def set_x_range(self, lower_limit, upper_limit):
        self.ax.set_xlim([lower_limit, upper_limit])

    def set_y_range(self, lower_limit, upper_limit):
        self.ax.set_ylim([lower_limit, upper_limit])

    def set_legend(self):
        self.ax.legend(loc='upper left', bbox_to_anchor=(1, 1))  # グラフの右上外部に配置

    def add_plot(self, x_data, y_data, color=None, label=None):
        # self.ax.plot(x_data, y_data, color=color, label=label)
        self.ax.plot(x_data, y_data, color=color, label=label)
    
    
    def show_figure(self):
        plt.show()

    def save_as_png(self, path):
        self.fig.savefig(path)
        
```

```python
fig1 = MatPlotLogX()
fig1.set_x_range(10, 10000)
fig1.set_y_range(0.00001, 1)
fig1.add_plot(x_data, y_data, label='test')
fig1.add_plot(x_data2, y_data2, color='red')
fig1.set_legend()
fig1.show_figure()

```


```
import matplotlib.pyplot as plt
import japanize_matplotlib
import pandas as pd

if __name__ == '__main__':
    data = {
        'Tokyo': ['27\nHigh', '23\nLow', '27\nHigh\n \n※注意', '24\nMedium', '25\nHigh', '23\nLow', '26\nHigh'],
        'Osaka': ['26\nMedium', '23\nLow', '27\nHigh', '28\nVery High', '24\nMedium', '22\nLow', '27\nHigh'],
        'Osaka': ['26\nMedium', '23\nLow', '27\nHigh', '28\nVery High', '24\nMedium', '22\nLow', '27\nHigh'],
    }

    df = pd.DataFrame(data)

    fig, ax = plt.subplots(figsize=(8, 6))  # 図全体のサイズを調整

    ax.axis('off')
    ax.axis('tight')

    # テーブルの幅を調整 (bboxの4番目の値を変更)
    tb = ax.table(cellText=df.values,
                 colLabels=df.columns,
                 bbox=[0, 0, 1.2, 1.5],  # 3つ目が表の幅、4つ目が表の高さ
                 cellLoc='left',
                 loc='center')

    # ヘッダー行の色とテキストプロパティを設定
    tb[0, 0].set_facecolor('#363636')
    tb[0, 1].set_facecolor('#363636')
    tb[0, 0].set_text_props(color='w')
    tb[0, 1].set_text_props(color='w')
    
    # 各行の高さを増やす
    for i in range(len(df) + 1):  # ヘッダー行を含む
        for j in range(len(df.columns)):
            cell = tb[i, j]
            cell.set_fontsize(12)  # フォントサイズを調整

    # 3行目の高さを0.5に変更
    for j in range(len(df.columns)):
        cell = tb[1, j]  # 3行目の各セル
        cell.set_height(0.05)

    plt.show()

```
Windows端末でDistrolessイメージを使用してDockerを起動する方法

## 前提条件

1. Windows 10 Pro、Enterprise、または Education（64ビット版）
2. Docker Desktop for Windowsがインストールされていること

## 基本的な手順

1. Docker Desktopを起動する
   - タスクバーのDocker Desktop アイコンをクリックする、または
   - スタートメニューからDocker Desktopを検索して起動する

2. PowerShellを管理者権限で開く
   - スタートメニューを右クリック
   - 「Windows PowerShell (管理者)」を選択

3. Chainguard社が提供する Wolfi イメージをプルする

```powershell
docker pull cgr.dev/chainguard/wolfi-base:latest
```

4. Wolfiイメージを使用してコンテナを起動する

```powershell
docker run -it --rm cgr.dev/chainguard/wolfi-base:latest
```

5. コンテナ内でコマンドを実行する

6. コンテナを終了する

Ctrl + D を押すか、exit コマンドを実行する


## 補足

Chainguard社が提供するstaticイメージで同様の事を実施します。

```powershell
docker pull cgr.dev/chainguard/static:latest
```

Chainguardの static イメージを単純に実行しようとすると、以下のようなエラーが発生します

```
docker: Error response from daemon: No command specified.
See 'docker run --help'.
```

これは、static イメージが実行するデフォルトのコマンドを持たないために発生します。
このイメージは主に他のイメージのベースとして、または静的ファイルの配布用に設計されているためです。
対話的な使用には、chainguard社が提供する wolfi イメージなど、より多くのツールを含むイメージを使用できます。

## 結論

- Chainguard Distrolessイメージ（特に static イメージ）は極めて最小限の構成のため、ほとんどの一般的なLinuxコマンドやツールは含まれていません。
- これらのイメージは主にアプリケーションの実行環境として設計されており、対話的な使用には適していません。
- 実際の使用では、このイメージをベースにしてアプリケーションを含むカスタムイメージを作成することが一般的です。
- Chainguardは複数のDistrolessイメージを提供しています。
- 特定のアプリケーションやランタイムに適したイメージを選択することができます。
イメージOS　〜画像アプリ用のあたらしいNoCode (ノーコード)〜　

私は、ほしい機能（表現）があった。

それはアニメのフレーム補完が可能なベクター線に、強弱や質感（水彩や鉛筆など）をつけることだったりする。そんな機能を持ったソフトは、確かに存在するかもしれない。

けれど、そういった独自に欲した機能は、**多くのソフトの中のどのソフトにあるのか？**
簡単には探し出せない。

![9VAeでのベクターアニメーション作成（画像）](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658140/af583973-50f8-2071-634b-86d9097dcb51.png "9VAeでのベクターアニメーション作成")
*9VAe ベクターアニメ編集画面*

また、そのソフトはどんなソフトだろうか?
例えば先程のような機能に似たものは（静止画のみだが、、、）ClipStudioPaintoに存在する。しかし、そのツールは**プロが使ういわゆる機能がうじゃうじゃあるツール**であり、その機能はそのうじゃうじゃある機能の中のマイナーな機能の一つに過ぎない。

![クリップスタジオペイントの画面（画像）](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658140/36096c85-091f-445e-ad3e-39dda43ad8ed.png "クリップスタジオペイントの画面")
*clipstudiopaintoの編集画面*

そのソフトを、**必要な１つの機能があるというだけの理由で導入するべきだろうか?**

うじゃうじゃとうごめく機能を習得してその機能を使う段階までにたどり着くのに、どれほど時間がかかるか、考えただけでその機能を諦める。

そして、すくなくとも導入を考える時点で言えば、それは**まだその機能自体は使えていない段階**にある。
ネットでこんな機能があるという紹介（使い方）が載っていただけ。

そうなると、機能の詳細がわからない。私自身も、このClipStudioPaintoにあるという機能は自分の思うものかわからない。

## 必要なのはこれ。
つまり、アプリという枠を超えて機能を交換できる方法が必要なのだ！！

* ほしい機能を**素早く**見つけられる。
* ほしい機能は**使い慣れたツールに落とし込める。**
　→簡単に動作を把握し、**試しに使う**ことができる。
* 機能はもっと細かい機能から構成されていて、**細かなカスタマイズや改造**ができる。（←どれくらいの細かさで階層を統一するか）（改造するにあたって著作権をどのように管理するか）
* 詳しい者はコードを書いて、詳しくない者は機能を組み合わせ、レイヤー（機能）を作っていく。
　→機能の細かさの階層構造はこのような能力に応じたカスタマイズを可能にする。

## どのようにして実装するか
まず機能は私が作るのでは間に合わないし、
ユーザーが自身で追加できないのでは**ユーザーのニーズに合った機能が作れない**。
そこで機能は、ユーザーや外部からのプログラマーなどに作ってもらう。

定型的な基盤となる機能のそろったアプリ（いわゆるユーザーが機能を付け加えていないVScode）はない方が良い。
**→ユーザーの欲しくない機能**が常に存在することになる。

できるだけ機能どうしを自由につなげられるとよい、とわかる。（それは情報の受け渡し等。）**→できないとプログラムに詳しくないユーザーの思いつきに対応できない**

そこで、ユーザー同士で決まりを作る。すなわち規格化を図る。
規格化はデータのやり取りや、プログラムの領域などを決定し使用していくことだと思われる。
ここで２つの課題が残る。
* 基盤となるアプリ等がないため**実態がない。**
（つまり、こういう規格があります、と世のプログラマーに伝えても、規格（規則）だけではプログラマーに何も作るメリットがない。）
* 他人の作ったプログラムを実行することは**セキュリティ上危険。**

この２つの課題を解決する方法がある。
セキュリティシステムとして機能たちを管理する**最低限のOSアプリケーションを作ってしまう**ことだ。

## どのように機能を組み合わせるか
デジタルで絵を描く時に必要な、**レイヤー**を使う。

レイヤーとは、透明なセルのようなもので、その上に絵を描き、重ねていくもの。
ほぼすべてのペイントソフトはこの形式で絵を描いていく。（あくまでアプリ上の話なので、実際に透明なセルはないよ。）

![レイヤー構造の仕組み（画像）](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658140/230a158c-c8d2-64ff-3e13-61f6e3784f98.png "レイヤー構造の仕組み")

レイヤーにひとつの機能をつけ、**重ね合わせることで新しい機能を作る。**
これなら、日頃、絵を描いている人にもわかりやすい〜♪
のではないかと思っている。

具体的には、下のレイヤーが上のレイヤーへデータを渡していって、機能（フィルター）が重なっていくように見える。

![レイヤー間のデータの受け渡し（画像）](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658140/8f9a3028-b320-98f6-61d7-5246f90fd572.png "レイヤー間のデータの受け渡し")


ただし、レイヤーの入力値、出力値は種類が多くなった場合、レイヤーとして重ねるだけでなく、バックグラウンドまで編集せねばならず、複雑になるかも。

## イメージOSの機能
* プログラムレイヤーのインポート
* レイヤーの管理
* レイヤーを組み合わせて実行（サンドボックス）
* ブラウザーとのハードウェア情報連帯（情報交換）

また、このようなプログラムは私一人ではセキュリティ等専門知識が不足しているため、オープンソースプロジェクト（OSS）として共同開発する必要がある。

## ということで、、、
イメージOSについて私のアイデアをメモしておきます。

今年（２０２４年）の夏までに
Githubにてコードを公開すると思います。（夏休みを賭けます！）

そして、OSSをやろう！
という大胆な計画ですが、去年からパソコンに触れ始めた私は全く知識がありません。（いま、Gitの使い方を勉強しているという、、、）

公開するコードも、とても危ういと思います。

なので、**できれば皆さんから、OSSを行うにあたって、アドバイス頂きたいです。**
また、質問があったら教えてください。
　
　
一応、開発状況はこちらから →　https://github.com/shikiishi/imageOS

また、テスト版が完成したので使ってください。↓↓
　　　　　https://shikiishi.github.io/imageOS/HTML.html
作成した学習管理アプリのデータを永続化し、CI/CD環境を構築しました！

## はじめに
以前Reactの入門として作成しました「学習管理アプリ」について、
タイトル通りデータを永続化し、Githubへのプッシュ時に自動でテストコードを実行し、Firebaseにデプロイされるように機能を追加しましたので、機能のご紹介と所感について記事にしてみます！

<br/>
↓参考（前回の記事）

https://qiita.com/Kei-dev-1213/items/bb35b05b0c5ab885e86e

## アプリに追加した機能
まず機能追加後のアプリはこんな感じです↓。
![画面収録 2024-08-03 15.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3832049/764debd1-a3df-c214-13fe-5822ea0737d7.gif)

見た目のスタイルは前回と変わっていませんが、今回は学習記録をsupabaseのテーブル上に保存しているので、画面を開き直してもデータが破棄されることはありません。
（初期表示時、登録時、削除時はsupabase上のテーブルにアクセスし、学習記録の取得、登録、削除を行うようにしています。）

また、本アプリのCI/CD環境として、Githubへのプッシュ時に自動でテストコードの実行、及びFirebase環境へのデプロイが行われるように設定しています。

こちら↓の記事がCI/CD環境設定時の記事になりますので、よろしければご参照ください。

https://qiita.com/Kei-dev-1213/items/aca49a9ad1ea8e75578a

## 所感
CI/CDってなんぞ？というレベルだったのですが、やっぱり自分で手を動かすことが一番頭に入ってきますね！
（ちなみに以下の記事が概念の理解のための参考になりました↓。）

https://qiita.com/shinkai_/items/13e76a5641d9ec9a41d2

今回は一人での開発（しかも簡易アプリ）でしたが、それでも初めて触ってみる概念や技術だったので結構苦労しました…
（supabaseとの連携の仕方、テストコードの書き方、Github Actionsの設定の仕方、etc...）
ただ、苦労した分だけテストが全てパスした瞬間や、Github Actionsのデプロイが最後まで通った瞬間は爽快でした！（プログラムはこの瞬間が一番楽しい）
**<font color="red">大事なのは詰まないことではなく、詰んでから解決するまで何を試したか（そこから何を学んだか）</font>** だと思います（というかプログラムを書いていて詰まない人は存在しない）。
今後の課題でもこの気持ちを忘れず最後まで突き進もう！と思いました。

## JISOUのメンバー募集中🔥
プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
気になる方はぜひHPからライン登録お願いします！👇

https://projisou.jp/
足し算 (paizaランク D 相当) Java解答例

# 問題文
https://paiza.jp/works/mondai/d_rank_skillcheck_sample/addition

# 解答例
```java
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		try (Scanner scanner = new Scanner(System.in)) {
			int a = scanner.nextInt();
			int b = scanner.nextInt();
			System.out.println(a + b);
		}
	}
}
```

# 補足
取得した数値を足して出力するだけなので特になし。