OmniAICreator/Qiita-1.07M huggingface dataset:
Bolt.newを使ってコーディングをせずにWebアプリを2時間でデプロイした話

# はじめに
### 私のスペック:pencil2:
- 業務ではAWSインフラ領域のチームリーダー
- プログラミング経験はGASで1年くらい(ほぼ忘れた)とPythonで2か月くらい(ChatGPTがほぼ書いた)
- アプリの作成経験無し

「絶対webアプリなんか作れるわけないだろ（笑）」という声が聞こえてきますが大丈夫です。私もそう思います。
そんな私がwebアプリケーションをどのようなステップで作成したのかをここに記します。

# 生成AIだけでアプリコンテストに挑むことになった経緯
アプリを作ることになったのは、社内でアプリコンテストが開催されることになったからです。
社内のアプリコンテストの準備期間は9月~12月と3か月も時間がありました。
しかし期限が決まっていたらぎりぎりまでやらないのが人間というもの。
私は夏休みが終わって初登校の日に、宿題を家に置いてきたと言い訳するタイプでした :v_tone1:
そのうち作ろうと思いつつ、何を作ろうか考えているうちに12月になり、今流行りの風邪なのかコロナなのかインフルなのかわからない体調不良になり、とうとうアプリコンテストの前日になってしまいました。
 
# **今回の構成**

ほんとにシンプルな構成です。
生成AIのいわれるがままに作成したので、DBは使ったこともないsupabaseを利用しています。:rolling_eyes:
Amplifyも今回初めて利用しました。前触ろうと思ったときはUIがわかりにくかったですが今は洗練されていてとても使いやすいなという印象を受けました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3811073/74620dd2-f847-2e5b-a3c9-d06baa03b39c.png)

# 使用した生成AI

### **Bolt.new**
- **用途**: アプリ作成全般
- **メリット**:
  - TypeScriptが得意で高品質なアプリを生成
  - コード修正時に即座にプレビュー可能
  - AIとのやり取りが高速化
- **デメリット**:
  - 有料版利用でコストが発生（1か月1000万token/20ドル）

:::note info
ハッピーホリデー🎄ってことでBolt.newのトークンが毎日20万token無料でもらえるらしいので、試すなら今がチャンス！
https://x.com/stackblitz/status/1870203756995911707
:::


### **ChatGPT**
- **用途**: アプリ作成以外の不明点解消
- **感想**: いつも通りの頼れるアシスタント
~~普段から課金しているのでコストは計上しません~~

# **プロジェクトの進め方**

### 1. **方針**:
   - 基本的にBolt.newにすべてコーディングを依頼します
   - アプリ以外の不明点はChatGPTで解消
### 2. **自分の役割**:
   - AWSへのデプロイ作業のみ

# **Bolt.newのここがすごい**
### 1.画面一つで完結
AIにプロンプトを送ると、画面右側でAIがゴリゴリコーディングしてくれて、一通り終わったらすぐにプレビューが見れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3811073/8e7a9d41-a103-b259-c844-c0fe3eb0644c.png)
以下プレビューです（プロンプトが適当過ぎて何がプレビューされてるのかよくわかりませんね）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3811073/56fe2d82-ae93-486c-2fd9-33441f8c83f7.png)

### 2.GitHub連携ができる
画面右上の「Open in StackBiltz」を押して
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3811073/718878e8-2187-bd49-09b9-53cb2e0e8f5b.png)
画面左あたりの「create a repository」から丸々リポジトリを作成できます！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3811073/3176f416-0674-91cc-4874-18356ace5988.png)

:::note info
Bolt側からGithubへ都度pushしたりはできなさそうだったので、私はアプリ作成が一通り終わってからリポジトリを作成しました。
:::

# アプリを作って感じたこと
#### *1回目のプロンプトが大事*
プロンプトを詳細に記載して1回目の出力が作りたいアプリに向いていると順調に作成できると思いました。
この辺は釈迦に説法になってしまうので割愛させていただきます。
気になる方は詳しく説明されている以下記事をご覧ください。

>参考
https://qiita.com/Ameyanagi/items/67f220df9c9240021048
https://qiita.com/fuyu_quant/items/157086987bd1b4e52e80

#### *TSやモダンJSについて学びたくなった*
生成AIが自動でコーディングしてくれるとはいえ、やっぱり自分のイメージを直接書き起こしてくれるわけではないので、もどかしさを感じましたね。
これを機にアプリ周りの学習をしたいなと思いました。

#### *たたき台はAIで十分*
生成AIを利用すれば**70~80%のクオリティ**は短時間で実現可能なことは分かりました。
凝りだしたり、あらゆるところを修正しようとすると、自分でコーディングできる人なんかはそこからは自分で実装したほうが早かったりするかもしれません。

## **最後に**

今やwebアプリケーション作成について全く知識がなくても、AIにプロンプトを投げ続ければ誰でもWebアプリを作れるようになったんだな、、、と身をもって実感しました。
とはいえ、やはり生成AIも完璧ではないですし、設計書を食わせて設計通りに作って！なんてのはまだまだ先の話だと思うのでこれからも変わらず勉強しなきゃですね。
TSやモダンJSの勉強ができたらまたBolt.new触ってみたいと思います。

それでは！
【RV指摘】三項演算子に関するコード

三項演算子に関するコードで冗長なコードを書いてしまい、RV指摘を受けたことがあるので備忘です！

いくつかのサンプルを用意したので、
コードを見て、リファクタリングを考えて見てください〜

## No.1 
* 元のコード
```
const isActive = isOnline === true ? true : false;
```
↓

* リファクタリング後
```
const isActive = isOnline === true;
```

* 解説
isOnline === true;　が真であれば、true、偽であればfalseということで、冗長な部分はなくすべし。

## No.2
* 元のコード
```
const isActive = (userAge >= 18) ? true : false;
```
↓

* リファクタリング後
```
const isActive = (userAge >= 18);
```

## No.3
* 元のコード
Array.includes を使用した簡略化
```
const isInList = list.indexOf(item) !== -1 ? true : false;
```
↓
* リファクタリング後:
```
const isInList = list.includes(item);
```

* 解説
indexOf を使って -1 をチェックしてから true / false を返さやり方より、includes メソッドを使えばスッキリ実現可能と。

## No.5
* parseInt の結果をそのまま利用

* 元のコード:
```
const parsedValue = parseInt(stringValue, 10) ? parseInt(stringValue, 10) : 0;
```
↓

* リファクタリング後:
```
const parsedValue = parseInt(stringValue, 10) || 0;
```

* 解説
parseInt の結果が NaN の場合、NaN は false として扱われるので、|| 演算子を使って簡潔に書けます。


以上です。

冗長なコードは、無くしていきましょう〜。
非推奨なコードの警告を消す「@Suppress("DEPRECATION")」を際の注意点

# はじめに
例えばアプリを使用している際のNetworkをモバイル回線を使用しているのか、Wifiを使用しているのかなどのNetwork関係を取得する際に
```
connectivityManager.activeNetworkInfo
```
などを使用した際に


```
'getter for activeNetworkInfo: NetworkInfo?' is deprecated. Deprecated in Java
```
このような警告が出ます。



https://developer.android.com/reference/android/net/NetworkInfo

公式からでも確認できるように
>This class was deprecated in API level 29.

この警告はアプリバージョンがAPI level 29以上の場合に違った方法でNetworkInfoを取得（または、それと同等の情報を取得）するように促す警告だと思います。

# 警告を消す
警告が出ているコードがあるメソッド、または、クラスの上に
```
@Suppress("DEPRECATION"
```
このアノテーションをつけることで警告を消すことができます。

# 注意点
警告自体を消すことができますが、非推奨の部分を見つけにくくする要因になってしまい、リファクタリングをかけた際にコーディングのクオリティを上げにくくなってしまいます。

わかりやすく言うと、無理やり警告を消しているだけでなんの解決にもなってないと言うことです。
もし使う際は慎重に使えるといいですね。


# 参考

https://qiita.com/omochimetaru/items/0b455d34a7ea2721d1b8

https://qiita.com/Natukasi/items/9cbfbe1cc3369b7537b2
GitHub Pagesで個人サイトを作ってみた！初心者の奮闘記

## はじめに
GitHub Pagesを使って個人サイトを作ってみました！といっても、まだ本当に作っただけで、ほとんど何もない状態ですが…。[こちらです！](https://ken1math.github.io/my-website/)  
以前、WordPressやGoogleサイトは使ったことがありますが、コードを書く必要がないので、「自分で作った！」という実感が薄いと感じていました。

## 作り方（調べ方）
「GitHub Pagesで個人サイトを作りたい」とChatGPTに相談して、教えてもらいながら進めました。  
基本的にはChatGPTで解決しましたが、ネット検索も少し活用しています。ChatGPTがとても優秀で、多くの方が書かれた解説記事も参考にできたので、大きくつまずくことはありませんでした。

エディタには以前使っていたVSCodeを使用しました。
GitHubのアカウントは以前から持っていましたが、ほぼ使ったことがない状態だったので、ほぼ初めての試みでした。

## 苦労した点

### VSCodeでのGit操作
VSCodeでGitを使うのは初めてで、最初はかなり苦戦しました。  
慣れの問題かもしれませんが、個人的にはVisual Studioの方が扱いやすいと感じています。  
本当はCUI（コマンドライン）で使えるようになるのが理想で、便利だと思うのですが、まだ慣れていません…。

### .gitignoreの後付け問題
Macで自動的に生成される`.DS_Store`を誤ってGitにアップロードしてしまい、それを削除するのに苦労しました。  
さらに、CUIでしか対応できないようだったため、それがまた大変でした。  

おまけに、`.gitignore`のファイル名を間違えるという凡ミスをしてしまい、それに気づくまでにも時間がかかりました。  
完全に削除するには履歴の書き換えが必要ですが、今回はそこまでせず、注意点を学ぶ良い機会になったと思っています。

## おわりに
ひとまず公開ができて、とても嬉しいです！  
ただ、GitHubの特性上、これまでの変更履歴がすべて見られるのはちょっと恥ずかしいですね。  
実際のところ、ただの上書き保存の感覚で進めているので、履歴はめちゃくちゃです。

今後は、共通部分をテンプレート化したり、デザインを整えたりしながら、作ったものを順次配置していきたいと思います。  
引き続き、楽しみながら取り組んでいきたいです！
Pythonの仮想環境構築手順メモ

Pythonを使用してプロジェクトを開発する際、異なるプロジェクト間で依存するライブラリのバージョンが衝突しないようにするためには、仮想環境を利用するのが一般的です。

## 仮想環境とは？

仮想環境とは、Pythonのインストールディレクトリやライブラリをプロジェクトごとに独立させる仕組みで、以下のメリットがあります。

- プロジェクト間の依存関係の衝突を回避できる
- プロジェクトごとに異なるPythonバージョンを利用できる
- グローバルなPython環境を汚さない

## 手順

### 仮想環境を作成する

Pythonでは標準ライブラリのvenvを使って仮想環境を作成できます。
以下のコマンドを実行して仮想環境を作成します。

python -m venv 仮想環境名

例:
```
python -m venv myenv
```

### 仮想環境を有効化する

作成した仮想環境を有効化するには、環境に応じて次のコマンドを使用します。

macOSの場合

```
source myenv/bin/activate
```

仮想環境が有効化されると、ターミナルの先頭に仮想環境名が表示されます。

例:
```
(myenv) $
```

## 必要なライブラリをインストールする

仮想環境を有効にした状態で、必要なライブラリをインストールします。

例: Flaskをインストールする場合

```
pip install flask
```

5. 仮想環境を無効化する

作業が終わったら仮想環境を無効化します。以下のコマンドを実行してください。

```
deactivate
```

## 注意点

仮想環境をプロジェクトごとに分けることを忘れないようにしましょう。
仮想環境のフォルダ（例: myenv）はプロジェクトディレクトリ内に作成することを推奨します。

必要に応じてrequirements.txtを使用して、依存関係を管理しましょう。

```
pip freeze > requirements.txt
```

```
pip install -r requirements.txt
```
Riderを使用していて、エディタータブがドラッグアンドドロップできなくなり、並び替えができず困った話

タブをアルファベット順にしているわけでもないし、エディタータブの設定にもそれっぽい設定がなくて本当困った
他の人はできるのに僕だけできない！
エディタータブが並び替えれない生活に耐えられない

# 結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1376552/43b0051b-db81-e36e-bced-907bc826b4da.png)

Altキーが押されたときのみドラッグアンドドロップを有効にするという項目が、外観にあった
最初のインストール時にIDEA風がデフォルトだと思って選んだらこれが有効になってたっぽい
助けてくれた友達ありがとう、ほんと
【VSCode】GitHub Copilotでコミットメッセージを生成する際のプロンプトを設定する方法

`settings.json`に以下のように記述することでコミットメッセージを生成する際のプロンプトを設定できます。

 ```json
 "github.copilot.chat.commitMessageGeneration.instructions": [
    {
      "file": ".github/COMMIT_CONVENTION/COMMIT_CONVENTION.md"
    },
    {
      "text": "Use conventional commit message format."
    }
  ],
```
ridgepoleでMySQLのテーブルにコメントがつかない場合の対処方法

[ridgepole](https://github.com/ridgepole/ridgepole)が便利でRailsを使う案件で大体使っているのですが、
テーブル自体にコメントを追加しようとしても追加できなかったので、その際の対処方法を記載します。

# 現象

```ruby:Schemafile
create_table "table_name", comment: "テーブルコメント" do |t| # <- テーブルコメント追記
  t.string "column"
end
```

上記のようにテーブルコメントを記載

```bash
$ ridgepole --apply
No change
```

実行しても変更無しと表示され、追加されない。

# 結論

以下のようにridgepole実行時に`mysql_change_table_comment`オプションを付けると追加されます。

```bash
$ ridgepole --apply --mysql_change_table_comment
-- execute("ALTER TALBE `table_name` COMMENT='テーブルコメント'")
   -> 0.0023s
```

# 確認

ridgepoleのソースの下記の場所に`mysql_change_table_comment`があるとコメントを処理するような記述を見つけたので試したところ動きました。

https://github.com/ridgepole/ridgepole/blob/afcbf509f24d4c67bc2cc310a7fc34f6bb0425f7/lib/ridgepole/diff.rb#L151-L155

検索した限りだと、ridgepoleで普通にテーブルコメント追加できるような記述ばかりだったので、
ridgepoleやMySQLのバージョンによったりするのかもしれないですが、
もし同じような現象に遭遇した場合は試してみてください。
ホームラボ（自宅検証環境）のススメ：技術を楽しむエンジニアがホームラボを作る理由と魅力

## はじめに
エンジニアとしてスキルアップや技術の習得を目指すなら、自宅に検証環境、いわゆるホームラボを作ることをおすすめします！

:::note warn
***私自身、2年前からWindows OS上に仮想化ソフトを導入し、手軽にサーバーを構築し、今では自宅にいくつものシステムが出来上がっています（笑）。***
:::

自宅にホームラボを持つエンジニアはまだ少ない印象がありますが、***この記事がきっかけとなり、ホームラボを作る方が増えたら嬉しいです！***

## なぜホームラボを作ろうと思ったのか？
***私の場合、正直なところ「気づいたら出来上がっていた」というのが正しい表現です（笑）。***

当時は、理解が難しいシステムや技術的な検証を行いたいという目的で、インターネット上で情報を調べながら作り始めました。

![スクリーンショット 2024-12-28 0.01.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/ed1969d4-8bc5-40fd-0ffa-e2444f781e0e.png)
引用画像：https://www.irasutoya.com/2016/04/blog-post_766.html

***昔から何かに熱中するととことんのめり込む性格もあって、システムを作って動かす過程がとても楽しくなりました。***

今後は、自宅に物理的なサーバーやネットワーク機器を導入することも本気で考えています（笑）。

:::note info
***このホームラボのおかげで、やりたい技術検証がある程度できる環境が整い、とても助かっています！***
:::

## 私のホームラボ環境について
私のホームラボ環境については、過去の記事で詳しく紹介しています。

![スクリーンショット 2024-11-29 9.58.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/7949f984-243f-47c3-bd4f-4b685e6c772e.png)

興味のある方はぜひご覧ください。

https://qiita.com/free-honda/items/bdce257a3407e1bb43b5

## 私がホームラボを作る理由
ホームラボを作る理由は大きく分けて3つあります。

![スクリーンショット 2024-12-27 23.59.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/119f61d9-2db2-6835-857b-191e14b677bb.png)
引用画像：https://www.tv-asahi.co.jp/riyuu/#/

それぞれ簡単にご紹介します（笑）。

### 安心して失敗できる環境
本番環境や会社のシステムでは試せない操作や設定も、自宅のラボ環境なら自由に試せます。

:::note
***失敗してもリスクが少なく、それがむしろ学びの糧になります。***
:::

### 実践的なスキルの習得
書籍やオンラインコースで得た知識を実際に試し、実践的なスキルとして定着させられます。

:::note warn
***特に、ネットワーク設定やサーバー構築、クラウド技術の模擬環境を作ることで理解が深まります。***
:::


### 趣味としての楽しみ
好きな機器や技術を使い、自分だけのシステムを作ること自体が楽しい体験です。

:::note info
***趣味として没頭できる点も魅力です。***
:::


## まとめ
私の場合、気づいたら「***失敗できる環境***」としてホームラボが自宅に出来上がっていました。

***今では、この環境を最大限に活用し、休日には技術を楽しみながら過ごしています。***

:::note alert
***実務や現場では、失敗が許されない場面も多いですが、自分だけの環境を作り上げることで、システムへの深い理解や技術的な知見を得ることができます。***
:::

この記事が、駆け出しのエンジニアの方や勉強を始めようとしている方にとって、一歩を踏み出すきっかけやモチベーションとなれば幸いです！

## おまけ
最近、私が主体的に開催している勉強会では、ホームラボをテーマにしたハンズオンを実施しており、参加者の皆さんもVirtualBox上でサーバーを構築する経験を積んでいます。

![スクリーンショット 2024-12-28 0.04.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/73c9f8f8-20cf-2fa1-af39-6b0f3f36aade.png)
引用画像：https://publicdomainq.net/students-study-0028177/

***今後、同じ志を持つ方々と、例えば「自宅で名前解決をしている」「自宅のデータベースにデータを格納している」といった技術に関する話題を共有できたら、とても嬉しく思います！***

私自身も、さらに難しいシステムや新しい技術に挑戦しながら、自宅のホームラボを進化させていきたいと思います。

:::note info
***これからも前向きに学び、コツコツとスキルを積み上げていきます！***
:::

## 関連記事

https://qiita.com/damepanda_supra/items/a3606cbe28c41508ec80

https://qiita.com/damepanda_supra/items/0151c04643985096ecd5

https://hironw.hatenablog.com/entry/2021/05/03/195800
【備忘メモ】anyenv, tfenv, AWS CLI に関する Tips

備忘のため、各 Tips をメモします。


## anyenv に関する Tips
### 


### xxenv を利用する際に注意すべき点
Terraform(tfenv) は問題ないが、anyenv でインストールできる xxenv のうち、pyenv などに関してはビルドされたバイナリを直接ダウンロードするのではなく、コードをダウンロードしてローカルでビルドするため、厳密にはノードごとに異なるバイナリが作成されてしまう模様。使用する際は要件に注意が必要。
具体的には、作成される各バージョンの python バイナリが実行ノードごとに異なるため、組織によってはxxenv の使用を認められないかも知れない。



## AWS CLI を使用する際のTips
### `aws configure` を実行する必要があるか
結論としては実行する必要はない。
`aws configure` コマンドは上記の認証情報ファイルの作成を対話形式で行ってくれるというだけである。

aws コマンドを使用できる状態であれば、${HOME}/.aws/ に以下のファイルを直接作成・記述すれば良い。
　${HOME}/.aws/config
　${HOME}/.aws/credentials
ただし、上記ファイルを手動作成した場合は、一般のファイルとして作成されてしまい、権限が 644(-rw-r--r--) となってしまうため、下記コマンドで権限を 600(-rwx------) に変更しておいた方が無難。
```
% chmod 600 ~/.aws/*
```

### ${HOME}/.aws/credentials の記載
`aws configure` コマンドではデフォルトのプロファイルのみが作成されるが、現実的には複数の AWS アカウントに接続をすることもあり得る。そこで、アカウントごとにプロファイルを分けて使用する。
Dockerコンテナを利用したNeo4jの環境構築とAPOCのインストール手順

## 要旨

日本語データでGraphRAGを動かすのに挫折したので、次の矛先として
ナレッジグラフを使ったRAGを実装した事例であるこちらの記事を、まったりと追試していく。
https://qiita.com/satken2/items/ea3ddc5f273d43cd63d4?utm_source=chatgpt.com

まずは以下の内容でNeo4jの準備から。

・Neo4jをDockerコンテナで起動する手順を記述する
・単一のコンテナで構成されるが、コンテナ起動時のオプションを明示的に記録するために敢えて`docker compose`を利用する

## Neo4jのDockerコンテナを起動する

### Docker Composeによる環境構築
Neo4jをDockerコンテナで運用する際、`docker run`コマンドでも起動可能だが、以下の理由から`docker compose`を利用する。

- 起動時のオプション（環境変数、ポート、ボリュームなど）を明示的に記録できる。
- 複数のサービスを一括管理する準備が容易になる。

以下は、`docker-compose.yml`の例である。

```yaml
dservices:
  neo4j:
    image: neo4j:latest
    ports:
      - "7474:7474"
      - "7687:7687"
    environment:
      NEO4J_AUTH: "neo4j/[8文字以上のパスワード]"
      NEO4J_apoc_export_file_enabled: "true"
      NEO4J_apoc_import_file_enabled: "true"
      NEO4J_apoc_import_file_use__neo4j__config: "true"
      NEO4J_dbms_security_procedures_unrestricted: "apoc.*"
    ulimits:
      nofile:
        soft: 40000
        hard: 40000
    volumes:
      - ./data:/data
      - ./logs:/logs
      - ./conf:/conf
      - ./plugins:/plugins
```

`docker-compose.yml`を保存後、以下のコマンドでコンテナを起動する。

```bash
docker compose up -d
```

起動後、`http://localhost:7474`にアクセスし、管理画面が表示されればOK。
管理画面には`docker-compose.yaml`で設定したID「neo4j」とそのパスワードでログインする。

## 動作確認

### テストデータの登録
起動したNeo4jにテストデータを登録する。

1. ブラウザ管理画面で以下のCypherクエリを実行し、ノードとリレーションシップを作成する。
    ```cypher
    CREATE (p:Person {name: "Alice", age: 30})-[:KNOWS]->(p2:Person {name: "Bob", age: 25})
    ```

2. 登録したデータを確認する。
    ```cypher
    MATCH (n) RETURN n
    ```

### データ永続化の確認
コンテナを再起動してデータが永続化されているか確認する。

1. コンテナを停止する。
    ```bash
    docker compose down
    ```

2. コンテナを再起動する。
    ```bash
    docker compose up -d
    ```

3. 再びCypherクエリを実行し、データが存在することを確認する。
    ```cypher
    MATCH (n) RETURN n
    ```

## APOCのインストール

### APOCとは
APOC (Awesome Procedures On Cypher) は、Neo4jにおける拡張機能の一つである。データ操作、外部データの取り込み、ランダムグラフ生成など、Neo4jの基本機能を拡張するプロシージャを提供する。
製品の標準機能として取り込まれた拡張機能も多々あるようで、とりあえずコアのAPOC入れておいたほうがいい、ということらしい。

### APOCバイナリのインストール
コンテナで起動したNeo4jにはAPOCのバイナリが含まれていないため、手動でインストールする必要がある。

1. Neo4jのバージョンを確認する。
    ```bash
    docker exec -it neo4j-neo4j-1 neo4j --version
    ```

2. Neo4jのバージョンに対応するAPOCを[GitHubリリースページ](https://github.com/neo4j/apoc/releases)からダウンロードする。
    ```bash
    wget https://github.com/neo4j/apoc/releases/download/<version>/apoc-<version>-core.jar
    ```

3. ダウンロードしたファイルをホストマシンの`plugins`ディレクトリに配置する。
    ```bash
    mv apoc-<version>-core.jar ./plugins/
    ```

4. コンテナを再起動する。
    ```bash
    docker compose down
    docker compose up -d
    ```

5. Neo4jブラウザで以下のクエリを実行し、APOCが利用可能になっていることを確認する。
    ```cypher
    CALL apoc.help('apoc')
    ```
# 感想
ブラウザの管理画面で直にSQL…ではなくCypherクエリを実行できること、その結果がなんというか昇順に表示されていくことなど、RDBMSしか知らない身からするとかなり風変わり（同時にめちゃくちゃ動作確認しやすくて好ましい）なインターフェースをしているように思う。

以上
inodeって何だ？-Linuxのファイルシステムの最初の難関

## ファイルシステムを勉強すると出てくる謎の言葉
linuxのファイルシステムを勉強していると、
ドライブやらパーテーションやら、論理ボリュームやら、
聞いたことがある言葉も出てくるが、その中で思いっきり分かりづらいのが、

**inode**

何だこれは。
しかもとても重要な意味を持っているらしい。
後々出てくる、**ハードリンクや、シンボリックリンク**
にも関わってくる？と聞いたので、調べねばならない。

## 本を読んで何となく理解する ##
まさに以下の本を読みながらLinuxを勉強しているのだが、

https://amzn.asia/d/ebCop1M

そこでのinodeの意味を抜粋してみよう。

>ファイルシステムにおいて、inodeはサイズ、オーナー、
>ディスク上のデータの場所、日付、パーテーションなどの
>個々のファイルに関するメタデータを保存する。
>しかし、inodeはファイル名と実際のデータを保存しない。
>ファイル名は、ディレクトリに保存する。
>ディレクトリはinodeをファイル名にマッピングしている。
（p86-87）

最初らへんは、分かる。
何に対しての”メタ”なのかわかっていないが、メタデータを持っているらしい。
ファイル名は持っておらず、ディレクトリがそれを保持しているらしい。

なるほど。。。

Kernelのファイルシステムで保持したinodeというメタデータを、
ディレクトリがファイル名にマッピングすることによって、
我々はディスク上の実際のデータに到達することができて、
ファイルを参照することができるのである！！

ということか。。。

 Kernel君、いつもファイルを参照させてくれてありがとう。
スライス(make、append、range)

### make

動的サイズの配列を作成する。
変数```d```に関して、容量は「スライスの開始位置から元の配列の末尾までの距離」に依存する。
```d```の容量 = スライスの開始位置から元配列の末尾までの要素数 = 5 - 2 = 3

```Go
package main

import "fmt"

func main() {
	a := make([]int, 5)
	printSlice("a", a)

	b := make([]int, 0, 5)
	printSlice("b", b)

	c := b[:2]
	printSlice("c", c)

	d := c[2:5]
	printSlice("d", d)
}

func printSlice(s string, x []int) {
	fmt.Printf("%s len=%d cap=%d %v\n",
		s, len(x), cap(x), x)
}
// a len=5 cap=5 [0 0 0 0 0]
// b len=0 cap=5 []
// c len=2 cap=5 [0 0]
// d len=3 cap=3 [0 0 0]
```

### append

スライスに新しい要素を追加する。
もし、元の配列が変数群を追加する際に容量が小さい場合は、より大きいサイズの配列を割り当て直す。

```Go
package main

import "fmt"

func main() {
	var s []int
	printSlice(s)

	// append works on nil slices.
	s = append(s, 0)
	printSlice(s)

	// The slice grows as needed.
	s = append(s, 1)
	printSlice(s)

	// We can add more than one element at a time.
	s = append(s, 2, 3, 4)
	printSlice(s)
}

func printSlice(s []int) {
	fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}
// len=0 cap=0 []
// len=1 cap=1 [0]
// len=2 cap=2 [0 1]
// len=5 cap=6 [0 1 2 3 4]
```

### range

```range```でスライスやマップ(map)をひとつずつ反復処理できる。

```Go
package main

import "fmt"

var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}

func main() {
	for i, v := range pow {
		fmt.Printf("2**%d = %d\n", i, v)
	}
}
// 2**0 = 1
// 2**1 = 2
// 2**2 = 4
// 2**3 = 8
// 2**4 = 16
// 2**5 = 32
// 2**6 = 64
// 2**7 = 128
```

インデックスや値は、 " _ "(アンダーバー) へ代入することで捨てることができる。

```
for i, _ := range pow
for _, value := range pow
```

インデックスだけが必要なのであれば、2つ目の値を省略できる。

```
for i := range pow
```

```Go
package main

import "fmt"

func main() {
	pow := make([]int, 10)
	for i := range pow {
		pow[i] = 1 << uint(i) // == 2**i
	}
	for _, value := range pow {
		fmt.Printf("%d\n", value)
	}
}
```
Chrome設定で横スクロール時の戻る・進むを無効化する。（Win/Mac）

Chromeでタッチパッドなどで横スクロールすると勝手に「←」「→」矢印が表示されて「ブラウザの戻る・進む」が実行されてしまうのは邪魔な機能だと思う人は多いと思います。

これまでも解決方法を記事にしていただいている方がいて、自分も過去にそれ通り設定して快適に過ごしていました。でも、ある日気づいた時からまた、横スクロール時のブラウザの戻る・進むの実行がされるようになっていました。

前に設定ができた、以下の方法で試そうとしてもバージョンの問題なのか、Chromeで項目が見つからずでした。

https://qiita.com/the_red/items/e1c3504fdd55e98a7dd3

## Chromeで「ページ間をスワイプ」のON・OFFは標準設定ができる。

そこで、
「**もしや標準機能になったということで、単に設定画面に項目があるのでは？**」とダメもとで探したところバッチリありました。

ブラウザ右上より、Chrome 設定を開きます。

![スクリーンショット 2024-12-27 22.41.31.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3972260/e9360dc4-a55e-73ad-2939-6f44585eba13.jpeg)



## Winの場合

Chrome 設定＞ユーザー補助機能＞ページ間をスワイプをスイッチオフにする

「ページ間をスワイプ」がONの状態
![D223354F-E974-4865-B899-796CC0277A74_1_201_a.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3972260/8fbc0d2a-a2e8-6a39-6400-899c60f110ac.jpeg)

「ページ間をスワイプ」がOFFの状態
![3DCE7974-85B0-4523-BA90-CFEF0C6A2F1E_1_201_a.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3972260/735d4b92-69f4-88f9-8825-368c1b920514.jpeg)



## Macの場合
MacはOSの設定でまとめて設定できるようです。

Chrome 設定＞ユーザー補助機能＞ページ間をスワイプ＞リンク先に飛ぶ＞「トラックパッド」の設定画面＞「ページ間をスワイプ」をオフにする


ユーザー補助機能＞ページ間をスワイプ＞リンク先に飛ぶ
![9EE83521-76B9-4F3D-9DD0-DBEA40B677F8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3972260/2245478f-986f-551e-b93b-fa5ae2e3b96b.png)



「ページ間をスワイプ」をオフにする
![145AB217-4D0E-4ED8-9D0E-9A3EB8F4D63E.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3972260/60baed16-a03c-03cc-ba50-e5f98a974ed0.png)


以上で、今後は操作が快適になります。

いつもブラウザで勝手に戻ってしまうたびにイラッとしていたり、「ブラウザ上で進めてた作業がやり直しじゃないか！」とショックを受けたことがある人は快適になるのでおすすめです！
【Dify】マルチエージェントAIで「戸建て住宅」と「賃貸住宅」のどちらに住むか判断させてみたTAKE2

# はじめに

前回に続いて「戸建て住宅」と「賃貸住宅」のどちらが良いかをマルチエージェントAIで判断してもらいます。

[【Dify】「戸建て住宅派AI」と「賃貸住宅AI」の意見から戸建て住宅を買うか買わないか判断させてみたTAKE1](https://qiita.com/ebi3kani3/items/5ba63665e545cdb1b703 "【Dify】「戸建て住宅派AI」と「賃貸住宅AI」の意見から戸建て住宅を買うか買わないか判断させてみたTAKE1")


## 環境
- 使用PC
ノートPC(Surface Go3 Laptop)
Windows11


- 使用ツール
Docker
Ollama
phi-3 mini(ローカル)
Dify(ローカル)

# 環境構築
以下のサイトを参考に環境を構築しました。

[Difyをローカル環境で動かす方法！ローカルだからこそのメリットや使い方を徹底解説](https://weel.co.jp/media/dify-local/ "Difyをローカル環境で動かす方法！ローカルだからこそのメリットや使い方を徹底解説")

# Take2
前回は「戸建て住宅派AI」と「賃貸住宅派AI」でしたが、今回は各方面の専門家AIを準備してみました。

![take4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3838427/c5ef79ad-367a-e4ce-6436-7f838d99fd85.jpeg)


専門家AIのそれぞれの役割は以下のとおりです。

- 経済AI：経済面から戸建てか賃貸かを判断するAI
- 心理学AI：心理面から戸建てか賃貸かを判断するAI
- 育児AI：育児面から戸建てか賃貸かを判断するAI
- 判断AI：各専門家の回答からどちらにするか判断するAI

それぞれに与えた指示を細かく見ていきましょう。
なお、私のローカルLLMでは生成する回答が長いとタイムアウトしてしまうため、回答が短くなるようにシステムプロンプトを少し工夫しました。

### 経済AI
システムプロンプト
~~~
"あなたは経済の専門家です。以下のインプットの情報から、
戸建て住宅と賃貸住宅のそれぞれの経済的メリット・デメリットを考えて
どちらか一方を選んでください。
なお、回答は以下のフォーマットとします。

フォーマット：
選択結果：
理由：(100文字程度)

インプット：開始/text
~~~

### 心理学AI
システムプロンプト
~~~
あなたは心理学の専門家です。
以下のインプットの情報から、戸建て住宅と賃貸住宅のそれぞれの
経済的メリット・デメリットを考えてどちらか一方を選んでください。

フォーマット：
選択結果：
理由：(100文字程度)

インプット：開始/text
~~~

### 育児AI
システムプロンプト
~~~
あなたは育児の専門家です。
以下のインプットの情報から、戸建て住宅と賃貸住宅のそれぞれの
経済的メリット・デメリットを考えてどちらか一方を選んでください。

フォーマット：
選択結果：
理由：(100文字程度)

インプット：開始/text
~~~

### 判断AI
システムプロンプト
~~~
あなたは戸建て住宅を買うか、賃貸住宅に住み続けるかを判断する人です。
以下のインプット1、インプット2、およびインプット3を基に、
戸建て住宅を買うか、賃貸住宅に住み続けるかのどちらかを判断してください。

インプット1：LLM1/{x}text
インプット2：LLM2/{x}text
インプット3：LLM3/{x}text
~~~



## 結果

入力
~~~
私は今賃貸住宅に住んでいます。最近戸建て住宅を買おうか迷っているので意見をください。 
現在は35歳の会社員で、妻と2人暮らし、子供はいません。
住まいは賃貸で、家賃は〇万円の2LDKです。 
世帯年収は〇〇〇万円、自動車の保有台数は2台です。
1,2年以内に子供が欲しいと思っています。
~~~

経済AIの回答
~~~
選択結果：賃貸住宅を維持する
理由：家財力の視点から、子育てに必要な出所が不足している。
家財は〇〇〇万円であり、安定した家賃が維持できます。
自分と家族の幸せ度を高めるために、余白をより大きくして子供を育むことが可能です。
~~~

心理学AIの回答
~~~
選択結果：賃貸住宅
理由：家賃は安定し、準備しやすく、大切な調整を必要とする家庭のため。
~~~

育児AIの回答
~~~
賃貸住宅を維持する。
理由：家賃が安く、経済的で、現在の子供を1,2年以内に生まれると期待しています。
~~~


判断AI
~~~
選択結果：賃貸住宅
理由：この地域では、家費は家賃を1,5倍以上支払う必要があります。
私は家賃が手順的に支払えやすく、安心できる環境を求めています。
また、子供が1,2年以内にいられるように、アドバンスドなサービスが提供されており、これによって家賃を抵払う機会が増えます。
ただし、将来的な物件の価格上げに注意しつつ、現在手元でいる金額を有効活用することが重要です。
~~~

## 結論
　AIの回答には納得いきませんが、どの専門AIも「賃貸住宅」を推していますね。
 私が今賃貸に住んでいるという情報を与えたからでしょうか。それとも学習データにそういったバイアスがあるかも？

もう少し細かいシステムプロンプトを書きたいところですが、私の貧弱なノートPCではここら辺が限度のようです。
【DXライブラリ】好きなフォントを使えるようにする

# はじめに
DXライブラリで好きなフォントを表示したい際に見てください

ゲーム起動時にPCにフォントがインストールされていないことを考慮しています

# 今回の主役
:::note info
## AddFontResourceExA - < Windows.h >
Windowsにフォントをシステム終了時まで読み込ませます

## RemoveFontResourceExA - < Windows.h >
AddFontResourceExAで読み込んでいたデータを破棄します

## CreateFontToHandle - "DxLib.h"
好きなフォントをDXライブラリ用に作成します

## DrawStringToHandle - "DxLib.h"
CreateFontToHandleで作成したフォントハンドルを使用し、文字を描画します
:::


# フォントダウンロード

今回はこのサイト様でダウンロードさせていただきました。


https://fontfree.me/3059

# フォント配置

フォント(.ttfファイル)をプロジェクトフォルダ近くに移動します

![スクリーンショット 2024-12-27 233613.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3847430/7b1e489b-dbb9-aa8c-364a-b6f9352d891c.png)

# フォント名を確認

.ttfファイルをダブルクリックし、フォント名を確認

![スクリーンショット 2024-12-27 233627.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3847430/55c9bbb2-30dc-7bb1-c1e0-de9bbef64d1a.png)

:::note info
このフォントでは「モギハ・ペン字Font」がフォント名です。

他のフォントを使用する際には
CreateFontToHandle引数のchar *FontName をそのフォント名に変更してください
:::

https://dxlib.xsrv.jp/function/dxfunc_graph2.html#R17N10



# 実装

```cpp:main


#include "DxLib.h"
#include <Windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    ChangeWindowMode(true);
    SetGraphMode(1000, 1000, 32);
    if (DxLib_Init() == -1) return -1;
    SetDrawScreen(DX_SCREEN_BACK);

    // ウィンドウズPCに一時的にフォントデータを読み込む(システム終了まで)
    // NOTE: .ttf→フォントデータ（トゥルータイプフォントの略）
    AddFontResourceExA("mogihaPen.ttf", FR_PRIVATE, NULL);

    // フォントハンドルの作成
    int fontHandle = CreateFontToHandle("モギハ・ペン字Font", 20, 3, DX_FONTTYPE_ANTIALIASING);

    // ゲームループ
    while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0)
    {
        // 裏画面をクリア
        ClearDrawScreen();

        // フォントを利用して文字を描画
        DrawStringToHandle(0, 0, "自分のフォント123ABC", GetColor(255, 255, 255), fontHandle);

        // テストフォント描画
        DrawFormatString(0, 50, GetColor(255, 255, 255), "デフォルト123ABC");

        // 裏画面と表画面を入れ替え
        ScreenFlip();
    }

    // フォントハンドルを削除
    DeleteFontToHandle(fontHandle);

    // ウィンドウズに一時的に保持していたフォントデータを削除
    RemoveFontResourceExA("", FR_PRIVATE, NULL);

    // ＤＸライブラリ使用の終了
    DxLib_End();

    // ソフトの終了
    return 0;
}

```
[OutSystems]Web Developer Specialization (ODC)のサンプル問題について解説 1/2 (#1-#5)

OutSystemsの新試験、Web Developer Specialization (ODC) は、ODCで行うWebアプリケーション開発について、Associateよりも踏み込んだ知識を確認する。

受験の前提がAssociate Developer (ODC) 。

Architecture Specializationと共にODCを対象とするProfessional認定条件の1つ。この2つに、2024/12時点では未発表の残り1試験を合格すると、Professional Web Developerとして認定される。

以前リリースされた試験では、サンプル問題はzipファイルの中にpdfファイルとして含まれていたが、この試験では、オンラインのコース上の１ページとして配置されている。
https://learn.outsystems.com/training/journeys/web-developer-exam-2993/sample-exam/odc/2990

全部で10問で、この記事では1問目-5問目が対象。
6問目-10問目

https://qiita.com/jyunji_watanabe/items/fc4aa5a089930e145e7e

サンプル問題は英語しかなかったので、この解説は英語版を見ながら書いている。

選択肢には番号が振られていないので、こちらで上から順に1,2,3,4をふっている。

# 1 Exception/Transaction Handling
Entityを操作（レコード作成）するメインの処理実行後に、Service Actionで監査ログを記録している。そのService Actionは、メイン処理で作成したレコードの存在チェックをし、見つからなければ例外をRaiseする。

問題文の設定では、Service Action実行時に例外が発生しているが、この時トランザクションはどうなるだろうか？　という問題。

まず、「メイン処理とService Actionは別トランザクションになる」点に注意。これはService ActionがHTTPS経由で呼び出される処理であるため、同じ RDBトランザクション管理下にないため。

また、メイン処理ではレコード作成が行われているが、問題文に添付されたActionフローにはCommitTransaction呼び出しが配置されていない。この場合、メイン処理のEndに到達した段階でコミットされる。よって、「Service Action実行時点では、メイン処理はコミットされていない」。

もちろん、Service Action中で例外が発生しているので、その処理はコミットされていない。

まとめると、メイン処理から呼ばれるTransferFundsも、Service Action AuditLogTransactionもコミットされない。この説明に合致する選択肢2が正解。

# 2 Best Practices - Data
Entityの参照属性が持つDelete Ruleについての問題。
問題文の画像を見ると、ProductImage EntityでProduct Entityを参照するProductId属性のDelete Rule=Protect。つまり、あるProductレコードを参照するProductImageレコードが1つでもあると、そのProductレコードは削除できない。

この説明に合致する選択肢3が正解。

ちなみに、Productレコードと一緒に参照するProductImageレコードが消えるとする選択肢1はDeleteの場合の説明。

# 3 Asynchronous Processes
各選択肢を見ていく。

1. ×：[OutSystems system requirements for ODC > Platform Limits - ODC Documentation](https://success.outsystems.com/documentation/outsystems_developer_cloud/getting_started/outsystems_system_requirements_for_odc/)によると、1 Appあたりの同時Events数上限は10でなく100
1. ○：マイクロサービス（App）間で非同期・疎う結合にやり取りをするのはEventの重要な性質
1. ×：Publicであるかどうかに関わらず、Eventは定義したApp自体もSubscribe可能
1. ×：エラー時には間隔を広げながら10回までリトライする

# 4 Work in Teams
複数の開発者が同じAppの同じ場所に開発を行った場合、後から行ったPublishで何が起きるか、という問題。
先に行ったPublishと競合が発生すると、競合が検知され、その内容を確認してマージを行うダイアログが表示される。マージを行って競合を解決するとPublishを実施できる。

よって、Publishするには競合の解決が必要、とする選択肢2が正解。

# 5 Best Practices - Data
バイナリデータを持つEntityをどう設計するか、という問題。
OutSystems 11の頃からのベストプラクティスがあり、当時からよく問題が出題されていた。
今検索してみると、ODC向けにもベストプラクティスが最近公開されており、同じベストプラクティスがあった。

[Best practices for data management > Isolate large text and binary data in separate entities - ODC Documentation](https://success.outsystems.com/ja-jp/documentation/outsystems_developer_cloud/building_apps/data_management/best_practices_for_data_management/#isolate-binary-data)

バイナリデータや大きなText型を属性に持つEntityはパフォーマンスが劣化する。そのため、ベストプラクティスは、バイナリデータや大きなText型は別のEntityに分離する。

この問題の場合、従業員の写真であるから、親Entityのレコードと写真Entityのレコードの多純度は1:1。よって、写真EntityのIdは親EntityのIdとする。

この内容を説明している選択肢4が正解。
Githubの使い方 : [新卒時代に戻って学び直すシリーズ]

- Gitとは
    -  プログラムの更新を記録してくれる
    - 複数人で開発するときに、効率を高めてくれる
- インストール方法
    - Homebrewを用いて、インストールする
- github
    - gitを公開する場所
    - gitとgithubは別物
- github コマンド
    - ```git config --global user.name "ユーザーネーム"``` 
        - githubにユーザーネームを登録する
    - ```git config --global user.email メールアドレス```
        - githubにユーザーネームを追加する
    - ```git init```
        - リポジトリを新規に作成」するときに使用するコマンド
    - ```git add [ファイル名]  ```
        - gitをステージングエリアに置く
    - ```git commit -m "最初のコミット" ```
        - gitをコミットする
    - ```git add -A```
        - 全てのファイルを、stagingに入れる
    - ```git log ```
        - gitの履歴を確認する
    - ```git remote add origin [url名]```
        - aa
    - ```git push```
        - リモートのリポジトリにあげる
    - ```git clone [url名]```
        - ローカルにリポジトリを持ってくる
    - ```git clone [url名] ファイル名```
        - 新しいファイル名をつける
LINE Messaging APIとGASでGoogleスプレッドシートに書き込もう

# はじめに
今回の記事では、LINEのMessanging APIを用いて、送られた内容をスプレッドシートに反映するということをします。
GASというのはGoogle Apps Scriptの略です。
# LINE Messaging APIとは
LINE公式アカウントで使用することができるAPIです。
メッセージの送受信をすることができ、LINEと様々なサービスを連携することができます。
送信は料金がかかるのですが、受信に対するアクションは無制限にできるので、気軽にLINE Botを作ることができます。
LINE BotというのはLINE上で動作するプログラムで、有名なものだと[リマインくん](https://page.line.me/aum5545l)などがあります。

# GAS(Google Apps Script)とは
Googleが提供しているプログラミング環境です。
GoogleスプレッドシートやGoogleカレンダーなどと簡単に連携することができ、いろんなことの自動化に向いています。
LINE Messaging APIと相性がいいので、よく組み合わせて使われます。
Google Drive上で作成することができます。

# 最初にやること
LINE公式アカウントを作り、messanging APIを使えるようにしてください。
messangingAPIのやり方については[こちら](https://developers.line.biz/ja/docs/messaging-api/getting-started/#using-console)をご覧ください。
GASを新規作成してください。
Googleスプレッドシートを新規作成してください。
# プログラム
以下のプログラムをGASに貼り付けてください。
```javascript:コード.gs
//固定値
var channel_token = "チャネルアクセストークン"

var url = "https://api.line.me/v2/bot/message/reply";

var spreadsheet = SpreadsheetApp.openById("スプレッドシートのID");
var sheet = spreadsheet.getSheetByName('シートの名前');

function doPost(e) {
  var json = e.postData.contents
  var events = JSON.parse(json).events;
  var event=events[0]

  //メッセージタイプがテキストか確認
  if (event.type == "message") {
    //メッセージテキストを取得
    var user_massage = event.message.text; 
    //スプレッドシートの一番下の行にメッセージテキストを追加
    sheet.appendRow([user_massage]);

    if (event.message.type == "text") {

      //自動返信メッセージ
      var message = {
        "replyToken": event.replyToken,
        "messages": [{ "type": "text", "text": "入力を完了しました" }]
      };
      //返信メッセージのオプション
      var options = {
        "method": "post",
        "headers": {
          "Content-Type": "application/json",
          "Authorization": "Bearer " + channel_token
        },
        "payload": JSON.stringify(message)
      };

      //自動返信メッセージを送信する
      UrlFetchApp.fetch(url, options);
    }
  }

}
```
固定値のところには適切な値を入れてください。
[スプレッドシートのIDについてはこちらをご覧ください](https://blog-and-destroy.com/33158)
[チャネルアクセストークンについてはこちらをご覧ください](https://developers.line.biz/ja/docs/messaging-api/channel-access-tokens/#what-are-channel-access-tokens)
# 反映
GASの内容を保存して、``新しいデプロイ``をしてください。
このとき、ウェブアプリとしてデプロイするのと、アクセスできるユーザーを全員に変えることを忘れないでください。
また、アクセスを承認する必要があることがありますが、[こちら](https://programming-zero.net/gas-webapp-deploy/)を参考にして進めてください。
デプロイしたURLをコピーして、LINE Official Account Managerの``設定 > MessangingAPI``の``Webhook URL``のところにペーストして、保存を押してください。
# テスト
公式アカウントを友達追加して、何か言葉を送ってみてください。スプレッドシートに書き込まれると思います。

# 応用
スプレッドシートをデータベースのように使い、LINEで動作するのでサーバーサイドもフロントエンドもあまり気にすることなくプロジェクトを開発することができます。
ぜひちょっとしたサービスの構築に使ってみてください。

Googleスプレッドシート関連のクラスやメソッドは[こちら](https://developers.google.com/apps-script/reference/spreadsheet?hl=ja)から調べることができます。
Time Machineのバックアップディスクが消えないときの対応

MacのTime Machineの設定画面に、物理的にマウントされていないディスクが表示され続ける状態になった。
次のファイルをリネームまたは削除で表示が消えた。
/Users/ユーザー名/Library/Preferences/com.apple.TimeMachine.plist
【Dify】「戸建て住宅派AI」と「賃貸住宅AI」の意見から戸建て住宅を買うか買わないか判断させてみたTAKE1

# はじめに

マルチエージェントAIが流行ってきたので、流行りに乗って私も何かやってみようと思い立ちました。

## 環境
- 使用PC
ノートPC(Surface Go3 Laptop)
Windows11


- 使用ツール
Docker
Ollama
phi-3 mini(ローカル)
Dify

# 環境構築
以下のサイトを参考に環境を構築しました。

[Difyをローカル環境で動かす方法！ローカルだからこそのメリットや使い方を徹底解説](https://weel.co.jp/media/dify-local/ "Difyをローカル環境で動かす方法！ローカルだからこそのメリットや使い方を徹底解説")

# Take1
まずは試しにphi-3miniを3つ使って、以下のようなワークフローを作ってみました。

![take1_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3838427/6cc2b992-5076-8444-036f-751ea4ab5680.jpeg)

3つのAIのそれぞれの役割は以下のとおりです。

- 戸建て住宅派AI：戸建て住宅のメリットを述べるAI
- 賃貸住宅派AI：賃貸住宅のメリットを述べるAI
- 判断AI：戸建て住宅派AIと賃貸住宅派AIの回答からどちらにするか判断するAI

それぞれに与えた指示を細かく見ていきましょう。

### 戸建て住宅派AI
システムプロンプト
~~~
あなたは家を買うことを推奨する派の人です。
以下のインプットに対して、家を買うことのメリットを述べながら答えてください。
~~~

### 賃貸住宅派AI
システムプロンプト
~~~
あなたは家を賃貸住宅に住み続けることを推奨する派の人です。
以下のインプットに対して、賃貸住宅に住み続けることのメリットを
述べながら答えてください。
~~~

### 判断AI
システムプロンプト
~~~
あなたは戸建て住宅を買うか、賃貸住宅に住み続けるかを判断する人です。
以下のインプット1、インプット2を基に、戸建て住宅を買うか、
賃貸に住み続けるかを判断してください。
~~~

今回は異なる意見を持った2つのAIと、それぞれの意見を聞いた上で判断するAIという2層としました。

## 結果

入力
~~~
私は今賃貸住宅に住んでいます。最近戸建て住宅を買おうか迷っているので意見をください。
~~~

戸建て住宅派AIの意見
~~~
もしあなたが今賃貸住宅に住んでいますが、それと比べ家を買うことは大きなメリットを提供します。
まず、家族や友人が集まる場所を確実に提供することができます。
次いで、自宅のプライドを高めることで、社会的な地位を象徴していることができます。
また、長期的に見れば、費やす出張の願望も実現しやすくなりますね。
~~~

賃貸住宅派AIの意見
~~~
私は現在賃貸住宅に住んでおり、それが良い選択だと思います。賃貸住宅に住むメリットとしては、安全性の面があります。
例えば、従業員や運転手など、屋内での疲れた人々は、通常の家を探しにくい状況下でも安心して居住できることがメリットです。
また、隣接する住宅との間に不都合が生じない可能性があり、予算管理も楽に行うことができます。
さらに、家を賃貸している場合、継続的な保守作業や修復工事が必要なのではなくなり、住む人々の心理的ストレスも軽減されます。
~~~

判断AI
~~~
\n- ホテル：インプット1にあるメリットを考えると、家を買うことで家族や友人が集まりやすくなる点、家のプライドを高めること、長期的に見れば出張の願望が実現しやすい点はあるものの、具体的なメリットと欠如点には注意が必要です。
家の費用や維持管理、予算の制限など、抑棂的に判断する必要があります。
\n\n- 賃貸：インプット2にあるメリットを考えると、安全性の面や予算管理へのメリットは明らかです。隣接する住宅による不都合が生じない点も、屋内居住者が安心して住むことを可能にするメリットです。
また、継維作業や修理工事の費用が発生せず、ホームメイクなどのストレスも減少します。
\n\n\nこれらのポジティブ・ネガティブな要素を総合的に分析した上で、余裕がある人として、家を買うことを選択するか、それとも現在の賃貸状に過ごし続けるべきかについては、個人的なライフスタッティング戦略や長期的な投資思考を試みることが重要です。
例えば家を買う場合には、信用性の高い供給源からの融資や契約を結ぶことで費用の安定化が可能ですが、賃貸では家を所有しないために低コストで生活を送ることができます。また、予算管理が重要な個人であれば、賃貸状の維持が一定期間できらいでしょ0う、安全性面についてはホテルの選択を視野に入れた場合も妥当なかったです。
~~~

## 結論
　ローカルLLMを動作させる環境がノートPCの都合上phi-3miniを使いましたが、全体的にLLMの回答が不自然ですね。日本語がうまく生成できていない、何となく日本ではなくアメリカの文化に基づいた回答な感じもします。

　今後、もう少し軽量で精度の高いLLMが出てくることを期待して、マルチエージェントAIの勉強を続けようと思います。

## ローカルLLMでのマルチエージェントAI動作に関する気づき@ノートPC
　今回私が使用したのがノートPCだったためか、実行するたびにOllamaのphi-3を停止、再起動しないと途中でタイムアウトするという事象が発生しました。

 私の環境特有の問題かもしれませんが、同様にローカルLLMを使ってマルチエージェントAIを作る方は気を付けてください。
react-native (react) を素早く書く方法（個人的見解）

## この記事はなに？

react-native (react) を素早く実装する方法に気づいたのでその共有をする記事です。

## 結論
一言で言うと、**できるだけ分割されていないファイルや関数を作ったのち、各種概念に整理すると素早く実装できる** となります。

理由は、実装時に記述の分離を頭から切り離すことができ、作業中の考える内容を減らすことができる（よりシングルタスクに近づけることができる）からです。


## この結論に至るまでの経緯

#### 筆者の実装方針
現在筆者は個人開発でreact-nativeを使っています。

そして、概念を深く理解しつつ品質も高められるようにNext.jsは使わずディレクトリパターン（ページビュールーティング+コンポーネント指向+HooksAPI）を再現しながら実装を進めています。


#### 上手くいかない日々
当初は以下のようなボトムアップで実装をしていました。

```:ボトムアップの実装手順
やりたいことを決める
      ↓
アーキテクチャ設計（viewとstateの概念の分離やcomponent単位での切出しなど）の理論に基づいてuseDataStateやTestScreenなど単一責任の部品を作成する
      ↓
部品を組み合わせる
      ↓
動作確認をする
```

ところが、部品を組み合わせる時や新しいコンポーネントを作成する時に「それぞれの粒度があっているか」や「テストが組みやすくできているか（疎結合にできているか）」といった点が気になってしまい、意味もなく同じファイルを行ったり来たりしてしまいました。

その結果、何が作りたかったか分からなくなってしまいモチベーションは下がり、作業スピードも遅くなってしまいました。

#### 見える兆し
それでも根性で開発は進めていました。

そしてある時、新しいコンポーネントを作成するためにいつものように v0 からデザインをもらい、何気なくそのソースコードを見て違和感を覚えました。

「なぜ同じ内容を実装しているのに、こんなに簡単なソースコードに思えるのだろうか？」と。


#### 結論にたどり着く
その理由を深掘りして最終的に出た結論が、上記でも書いた「頭の使い方をシングルタスクに近い状態にして実装（理解）ができるから」でした。


## まとめ

- 全体感を見失うとモチベーションが下がり開発速度も落ちる
- 対策として全てを含んだファイル作成をして後から分割する実装方法を選ぶと良い
- 筆者は設計書のないアジャイル開発においてボトムアップ実装をしてモチベーションが下がってしまったので、他の人が同じ轍を踏まないようにこの記事で情報を共有した


## ※注意
**ボトムアップ実装が悪いわけではない**ので誤解しないようご注意ください。

当初はボトムアップの良さの説明のためウォータフォールに関する内容も記事にしていたのですが、長すぎたので削除しました。

精度が求められる場合（開発コストをかけられる場合）はウォータフォール開発で設計書をしっかり準備してボトムアップ実装の方がより良いので、本記事はあくまでアジャイル開発の場合の記事としてご理解ください。
Unityの2D Tilemap Editorで2Dスクロールゲームを作ろう

簡単な2Dスクロールゲームを作りたい！
と思った時、Tilemap Editorという機能はとても便利です。
今回は2D Tilemap Editorを使った2Dスクロールゲームの作成方法について紹介します。



# 開発環境
- Unity6 6000.0.32f1
- Windows11
- VSCode

# 2D Tilemap Editorとは
ステージをタイルに区切って、タイルごとにテクスチャを張り付けてステージを作り上げるUnity機能です。
簡単にステージを作ることができるのでとてもおすすめです。

Unity Asset Storeの中にはタイルのアセットがいくつかあります。
これらを活用するとあっという間にステージを作ることができます。

ちょっとしたゲームを作る時、または本格的なゲーム制作でも十分活用できる機能だと思います。

Unity6の場合はデフォルトで入っているようです。
入っていない場合はPackage Managerから追加してください。

こちらがUnityの公式ドキュメントです。

https://docs.unity3d.com/Manual/tilemaps/tilemaps-landing.html

# Unityのプロジェクトを作ろう
Unity HubからUnityのプロジェクトを作成してください。
2Dにしましょう。

# Tilemap用のアセットを準備しよう

Tilemapに使う画像素材は自分で用意しても良いのですが、今回はAsset Storeにあるものを使ってみようと思います。

https://assetstore.unity.com/?category=2d%2Ftextures-materials%2Ftiles&price=0-2&free=true&orderBy=1

こちらが無料のTile素材です。
好きなものを選んでプロジェクトにインポートしてください。
私は↓これを使おうと思います。

https://assetstore.unity.com/packages/2d/textures-materials/tiles/pixel-tiles-for-side-scroller-141838


# ステージを作る
``Window > 2D > Tile Pallete``を開いてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/58feb7ca-e232-eeab-7f3a-fb50bceb0bd7.png)

ここがパレットです。絵具のパレットと同じように、ここでタイルを選択してステージに配置していきます。

今回はAssetStoreからインポートしたので自動的にパレットが作られていますが、自分の画像を使ったりする場合はここのCreate New Tile Paletteから作ってください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/7f906fd2-0641-b0f4-c28a-8205e1de3842.png)

次に、SceneにTilemapを作ります。

Hierarchyから、``2D Object > Tilemap > Rectangular``を追加してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/7b250a9e-691f-15ef-95c3-35f7c61202bc.png)

するとこのようにGridが作られ、Tileを配置できるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/ba58bfc0-c89c-0f1e-cfde-54dacf0a89ad.png)

これでタイルを配置できます。
Tile Palette上でタイルを選択し、Scene画面に配置してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/66960e23-ef6e-a3f9-8448-c610cb791a4c.png)

さて、この後地面や壁に当たり判定をつけるわけですが、この例でいう木のように、当たり判定をつけたくないものもありますよね。
そんなときはTilemapをもう一つ作り、当たり判定をつけるものとつけないものに分けます。
今回はこんな風にTilemapとBackgroundに分けてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/b351d7b7-f288-4bac-b204-66517317b42e.png)

次に、当たり判定をつけるTilemapにTilemap Collider 2Dというコンポーネントを追加してください。
これでTilemapに当たり判定が付きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/0679eebf-b55a-c90b-bb61-ed2036f50e60.png)

しかし、よく見るとタイル1つ1つにコライダーがついています。
これを合体させましょう。
Rigidbody2Dコンポーネントを追加し、Body TypeをStaticにした後、Composite Collider 2Dコンポーネントを追加してTilemap Collider 2DのComposite OperationをMergeにしてください。

これでコライダーが合体されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/fdf29f14-f1cc-2c67-35c0-5601b121734c.png)


ここにRigidbody 2D、Colliderを追加したプレイヤーや敵を追加すれば立派なステージの完成です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/57dd6008-1df7-99f5-b90e-4c234b0bc5f8.png)

プログラムを書いてゲームを作っていきましょう。
【VScode】ターミナルコマンド

ターミナルコマンド、一生覚えられないので（あまり使わないからってのもある）、備忘録として書きました。

**特定の場所に移動** (change directoryの略）
```
cd ~/     //ホームディレクトリに移動
cd ..     //１つ上の階層のファイルに移動する
```
**現在の場所を知りたい** (print working directoryの略)
```
 pwd   //カレントディレクトリのパスを表示
```
**ディレクトリ作成** (make directoryの略)
```
mkdir test　//testというディレクトリが作られる
```

**ディレクトリ削除**
```
 rm -r test   //中身が存在するtestというディレクトリを削除
```

**ファイル作成**
```
touch test.c　//test.cというファイルが作られる（一番小さい単位）
```

**ファイルの移動** (moveの略)
```
mv test.c tmp/    //test.cというファイルをtmp/に移動する
mv test.c test2.c   //test.cといるファイルをtest2.cに名前変更する
```

**ファイルの削除** (removeの略)
```
rm test.c   //test.cというファイルを削除
```

**ファイルのコピー** (copyの略)
```
cp test.c tmp/   //test.cというファイルをtmp/というディレクトリの中にコピー
cp test.c test2.c   //test.cをtest2.cという名前でコピー
```
**ファイルを開く**
```
code test.c   //test.cというファイルを開く
```

**余談**
 rmdir(remove directoryの略)コマンドも実在するらしいが、空のディレクトリしか削除できない
ミニPCでのマルチブート環境構築（Windows 11とUbuntu）

Linuxの学習を目的に、新しいミニPCを購入しました。購入したミニPCはWindows 11がプリインストールされており、Windows 11とUbuntuを切り替えて使用できるマルチブート環境を構築しました。

手順は下記の[Linux チャンネルの動画](https://youtu.be/NQjecsC4y-w?si=havJ8XzO-KmbDaIZ)を参考に進めました。とてもわかりやすいです！

本記事では動画で触れられていない問題が発生したため、その対処法を共有します。

## 使用したPCのスペック

- **モデル**: [GEEKOM NUC GT13 PRO](https://geekom.jp/products/geekom-nuc-gt13-pro?srsltid=AfmBOooR8W8VLuPOXH7Oclyh9y2vGH-0zCXC5Kej7UJzEYlphqgP_8NY)  
- **CPU**: インテル コア 第13世代 i7-13620H  
- **メモリ**: 32GB  
- **ストレージ**: 1TB SSD  



---

## マルチブート構築時のトラブルと対処法

### 1. USBからUbuntuを起動できない

BIOS設定でUSBからOSを起動できるようにBoot Orderを変更後、USBメモリからUbuntuを起動しようとしました。
![IMG_4825.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254759/f8c67d70-9a9e-1d25-0464-cdc3a48d6944.jpeg)



しかし、以下のエラーメッセージが表示され、インストール画面に進めませんでした。

**エラー内容**:  
`ERROR: Verification failed: (0x1A) Security Violation`

#### **対処法**  
BIOS設定を確認したところ、「Secure Boot」が有効になっていることが原因でした。以下の手順で解決しました。

1. BIOSにアクセス  
2. **Secure Boot**を「Disable」に変更  
3. 設定を保存して再起動

これにより、USBメモリからUbuntu起動ができるようになりました。

---

### 2. Ubuntuインストール後、Windows 11が優先的に起動する

Ubuntuのインストール自体は問題なく完了しましたが、再起動時にWindows 11が優先的に起動し、OS選択画面が表示されませんでした。

#### **対処法**  
再度BIOSを確認し、以下の設定を変更しました。

1. **UEFI NVME Drive BBS Priorities**の項目を編集
   - Ubuntuを最優先に設定
2. 設定を保存して再起動
![IMG_4849.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254759/2574073c-acb0-427a-4ea3-46a4b692940b.jpeg)
![IMG_4851.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254759/538cac76-b7fa-b31b-e3d3-9458ff88f8d2.jpeg)


これにより、起動時にOS選択画面（GRUB）が表示され、Windows 11とUbuntuを切り替えて使用できるようになりました。

### 2025-03-14 追記
マルチブート設定後、BIOSを開けない状態です。
なぜなら、OS選択画面（GRUB）にてファームウェアにアクセスする`fwsetup`コマンドがUEFIへのアクセスのみサポートしているためです。
マルチブート環境を構築するにはファームウェアがUEFIのPCを選択するべきです。

---

## まとめ

マルチブート環境の構築にはBIOS設定の変更が不可欠ですが、設定内容はPCのモデルによって異なるため、戸惑いますね。本記事が同様の環境構築を進める際の一助となれば幸いです。
Python のプログラムでPukiWiki にファイルを Upload

# はじめに
Bot Computing/Wiki IoT というのをやっています。これは、PukiWikiのページにかかれたスクリプトをIoTのEdge端末が実行し、実行結果をPukiWikiのページに書き加える、というものです。Edge端末がWikiのページの記述で遠隔操作されるBot となります。これをWiki Botと呼んでいます。

2024年1月には、Raspberry Pi Pico をWiki Botとして使えるようにしました。

https://qiita.com/takashiyamanoue/items/bb4b08c0f220ba4fd91a

その後、Wiki Botのプログラムを Python でも書いて、Raspberry PiでPython版のWiki Botを動かすことができるようになりました。

いままでは、Wiki Botは、PukiWikiのテキストページのみの読み書きを行っていましたが、音声や画像も扱えたら良いなと思っていました。そこで、今回、Wiki Botに音声・画像をWiki ページにuploadする機能を付け加える準備として、PukiWikiのページに
画像ファイルを添付するプログラムを作成することができたので、記録しておきたいと思います。

なお、Wiki Botを作る以前は、PukiWikiのプラグインとして Javaのアプレットを使って、音声や画像をテキストデータに変換してPukiWikiのページに保存することをやっていたのですが、Java アプレットが使えなくなってしまって、それができなくなってしまっていました。

# プログラム

Pico Wiki Driver を作った時と同様に、WireSharkでPukiWikiのページでファイルをuploadしたときのpostのデータをダンプ・解析するなどして作成しました。

```Python
import requests
from requests_toolbelt import MultipartEncoder

import mimetypes
file_Name = '<uploadする画像などのファイル名>'
file_dir='<uploadするファイルがあるpath>'
file_path=file_dir+file_Name

# MIMEタイプの定義
#XLSX_MIMETYPE = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
MIMETYPE = mimetypes.guess_type(file_path)[0]
print('file_path='+file_path)

# ファイル名とデータの取得
file_Data_Binary = open(file_path, 'rb').read()

# アップロード先のURL
url = '<PukiWikiサーバのURL>' 
page = '<ページ名>'

# アップロードするファイルの情報を辞書に格納
files = {'attach_file': (file_Name, file_Data_Binary, MIMETYPE),
         'encode_hint': 'ぶ',
         'pass': '<adminパスワード>',
         'refer': page,
         'pcmd': 'post',
         'plugin': 'attach'}

m = MultipartEncoder(files)

hx={'Content-Type': m.content_type,
#    'Accept:': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'Referer': url+'?'+'plugin=attach&pcmd=upload&page='+page
#    'Accept-Language': 'ja,en;q=0.9,en-GB;q=0.8,en-US;q=0.7'
}

# ファイルのアップロード
response = requests.post(url, data=m, headers=hx)

# レスポンスの表示
print(response.status_code)
print(response.content)

wfile_path=file_dir+'return.html'
result_file= open(wfile_path, 'w')
result_file.write((response.content).decode(encoding='utf-8'))
```

# 参考ページ等
以下のページなどを参考にさせていただきました。感謝します。

https://shiganai-coder.com/16061/python%E3%81%A8requests%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89/

https://note.nkmk.me/python-mimetypes-usage/
Kali LinuxでWindowsにRDPする方法

## はじめに
普段は業務でインフラの運用・保守をやっていますが、最近セキュリティに興味を持ち、TryHackMeで学習をしています。
今日はWindowsの基礎を学ぶと言うことなのですが、現在使っているPCがMacOS、セキュリティの学習のために使っているOSはKali Linuxです。（VMware Fusion Proが無償化したおかげで快適に使わせてもらってます。）Windows11のPCも持っているのですが、今日はあえて、RDPを使ってWindowsを利用してみます。

## Kali Linuxとは
Kali Linuxはセキュリティとペネトレーションテスト向けに作られたDebian系のLinuxディストリビューションです。豊富なセキュリティツールがプリインストールされているためセキュリティ分野のエンジニアやハッカーには必須のOSです。
デスクトップも厨二病心をくすぐる仕様です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3964004/d5db4e35-0519-6f53-5283-6fb046f2f27d.png)


## RDPとは
Remote Desktop Protocolの略称。Microsoft Windowsのリモート接続用プロトコルです。リモート環境で稼動しているWindowsコンピュータにアクセスし、操作することができます。RDPにより、デスクトップごと自分のPCのように操作可能になります。アクセスする際にはIP、ユーザID、パスワードが必要です。
Windows7以降にはデフォルトで「リモートデスクトップ接続」アプリとして入っています。Kali Linuxには入っていません。

## 実行
インストールされてないのに、実行？ってなりますよね。大丈夫です。
Terminalで以下のコマンドを入力
`xfreerdp /u:USERNAME /p:PASSWORD /v:MACHINE IP`
大文字の部分は必要な値に変更してください。
以下を使います。
![スクリーンショット 2024-12-27 21.33.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3964004/30ef40b2-d82a-2ad5-0fcc-20cb120efa37.png)
※これはTryHackMeが用意しているターゲットマシンのものです。
VPN接続しないとアクセスできないので、皆さんは使用できません。

コマンドを実行すると、「コマンド'xfreerdp'は見つかりませんが、インストールできます。インストールしたいですか？」と親切に聞いてくれるので、「y」と答えます。
パスワードを聞かれるので、入力すると自動的に`sudo apt install freerdp2-x11`が実行されます。

途中で続けますか？と聞かれるので「Y」
数秒でインストール完了します。

それでは改めて、下記コマンドを実行します。
入力大変なので、キーボード「↑」を押します。
`xfreerdp /u:USERNAME /p:PASSWORD /v:MACHINE IP`

正しく実行されれば、Windowsのデスクトップが表示されます。

もし、証明書検証で証明書の内容とホスト名が違っている場合は「信頼しますか？」
と聞かれます。
Y：一時的に信頼する
T：永遠に信頼する
N：信頼しない
のどれか一つを入力し、YかTであれば、Windowsのデスクトップ画面が起動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3964004/0c3d0cf8-4f0b-39ab-07b8-1139af152687.png)

# 終わりに
備忘録として、自分なりにまとめました。間違い等見つけましたら、指摘していただけると嬉しいです。
Let's enjoy Hacking!
Railsのdate_fieldに関するオプション(stepとtype)

# 検証条件
- Rails 7.1.3
- Ruby 3.3.3
- HTML5
- ブラウザ Google Chrome バージョン: 129.0.6668.70（Official Build） （arm64）


# stepオプション
stepオプションは、date_field の入力値の増減ステップを指定するために使用されます。

具体的には、step オプションを使うことで、ユーザーが日付を選択する際に、増減する単位（日数）を設定できます。

***＊注意***
```<input type="date">```をサポートするブラウザでのみ有効です。
サポートされていないブラウザでは、このオプションは無視されます。
無効な値を指定すると、ブラウザはデフォルト値の 1 を使用します。


### 設定値

#### ・1日単位(デフォルト)
ユーザーはカレンダーや日付ピッカーで、1日単位で日付を選択できます。

```
<%= form.date_field :birthday, step: '1' %>
```

![スクリーンショット 2024-12-27 21.07.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474880/d6659e17-026e-2210-341a-58360616d8b1.png)


#### ・7日単位（1週間ごと）の場合
日付ピッカーで日付を1週間ごとに選択できます。

```
<%= form.date_field :birthday, step: '7' %>
```

![スクリーンショット 2024-12-27 21.09.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474880/36b7177f-1ef1-81c5-52cf-89b2efc4b46f.png)

#### 任意の値を許可
JavaScriptと組み合わせて土日だけ選択させるケースなどに使用します。

```
<%= form.date_field :birthday, step: 'any' %>
```

## typeオプション
date_field の type オプションは、HTML5 の <input> 要素における type 属性を指定するためのオプションです。
date_field に関しては、type="date" がデフォルトの値です。

### 設定値

#### date

・デフォルトの設定です。
・日付を選択できます。
・入力形式は YYYY-MM-DD（例: 2024-12-27）となります。

```
<%= form.date_field :birthday, type: 'date' %>
```

![スクリーンショット 2024-12-27 21.26.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474880/8f5fccd4-8099-e9d9-f5ae-5bb78165b52a.png)

#### datetime-local
・日付と時間を選択、入力できます。
・入力形式は YYYY-MM-DDTHH:MM（例: 2024-12-25T15:30）となります。
```date_time_local_field```でも可
https://railsdoc.com/page/datetime_local_field

```
<%= form.date_field :birthday, type: 'datetime-local' %>
```

![スクリーンショット 2024-12-27 21.28.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474880/ea46cd9c-6a52-4724-ccfd-bd6441dc180e.png)

#### time
・時間（時間と分のみ）を選択、入力できます。
・入力形式は HH:MM（例: 15:30）となります。
```time_field```でも可
https://railsdoc.com/page/time_field

```
<%= form.date_field :birthday, type: 'time' %>
```

![スクリーンショット 2024-12-27 21.29.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474880/06165c6a-0ca0-e8c5-8aa7-45d771a6f763.png)

#### month
・年と月を選択、入力できます。
・入力形式は YYYY-MM（例: 2024-12）となります。
```month_field```でも可
https://railsdoc.com/page/month_field

```
<%= form.date_field :birthday, type: 'month' %>
```

![スクリーンショット 2024-12-27 21.30.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474880/5d26ef77-a348-8fed-853a-2968c09e667b.png)

#### week
・年と週番号を選択、入力できます。
・入力形式は YYYY-Www（例: 2024-W52）となります。
```week_field```でも可
https://railsdoc.com/page/week_field

```
<%= form.date_field :birthday, type: 'week' %>
```

![スクリーンショット 2024-12-27 21.31.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474880/0b6cf99d-3fcc-25e2-6ea8-5f7adde7f70d.png)