OmniAICreator/Qiita-1.07M huggingface dataset:
HP製マシン(Intel 12th CPU)にESXi7をセットアップ

# はじめに
とある検証環境を更改することになり、HP社製のマシンにESXi7をセットアップした際に躓いた点がありました。一連の流れを備忘として残します。
**※記載の内容は2023/11/1時点の情報です。**
# ESXiインストールメディアを準備
1. HP社製マシンにESXiをインストールするにはVMWare社提供のファイルではなくHPEカスタムイメージを落とします。
[VMware ESXi Image for HPE servers](https://www.hpe.com/us/en/servers/hpe-esxi.html)
2. ダウンロードしたカスタムイメージをメディアに焼きます。私は普段、USBメモリにインストールメディアを作成しております。作成時は[こちらのソフト](https://etcher.balena.io/)が使いやすく便利です。
# ESXiをインストール
1. マシン起動後、BIOS画面に入ってUSBメモリから起動させます。
2. ESXiロード画面にて「SHIFTキー」＋「O(オー)キー」を同時押しします。
5秒ほど経過してしまうと通常のインストールへ自動で進んでしまうので注意。
**なお、通常インストールへ入ると以下のような画面に出くわします。やり直しましょう。** 
最近のコンシューマ向けIntel 第12世代以降のCPUには、処理性能を求めたPコアと処理効率を求めたEコアがあり不均一な構成となるため、インストール時のチェックでESXiがパニックになるそうです。それを回避します。
参考画面(この画面が表示されインストールが中止される)↓
![IMG_0024.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472957/bdaf432f-c2f7-4ec5-2da2-9e5de7918561.jpeg)
3. コマンド入力
    - 画面上に表示されている文字列に空白一文字開けて、続けて「cpuUniformityHardCheckPanic=FALSE」 と入力します。
    - 画面を抜けて、通常インストールに進みます。前述の紫色の画面は回避されているはずです。
# インストール直後の操作
1. 「Installing Complete」画面が表示されましたら「Altキー」＋「F1キー」を同時押してDCUI(ESXiに備わっているダイレクトコンソールユーザーインターフェース)へ入ります。**Enterは押さないでください。**
![IMG_0027.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472957/ce49f05e-4a74-60e4-e0c3-63f481454598.jpeg)
2. コマンド入力
    - rootでログイン。（パスワードは空欄のままで良い）
    - コマンド入力 
        - vi /vmfs/volumes/BOOTBANK1/boot.cfg
        - VIエディタで起動時に読み込むcfgファイルを編集します。
    - cfgファイルの中身に「kernelopt=・・・」に続く文字列の最後に以下の文字列を追記します。
        - cpuUniformityHardCheckPanic=FALSE
    - 再度「Altキー」＋「F1キー」を押してCDUI画面から抜けます。
    - 「Installing Complete」画面に戻るので、マシンを再起動。
# 初回起動時の操作
1. ESXi通常のConfig画面へ入り、CDUIまたはSSHをONにする。
2. CDUIまたはSSHでESXiへログインして再度ターミナル画面を呼び出す。
3. コマンド入力（起動時のCPUチェックの設定を恒久的なものに変更する）
    - esxcli system settings kernel set -s cpuUniformityHardCheckPanic -v FALSE
    - esxcli system settings kernel set -s ignoreMsrFaults -v FALSE
4.  以下のコマンドを入力して値がセットされているか確認する。
    - esxcli system settings kernel list -o cpuUniformityHardCheckPanic
        - 「Configured」の列が「**FALSE**」になっていることを確認すること。
    - esxcli system settings kernel list -o ignoreMsrFaults
        - 「Configured」の列が「**TRUE**」になっていることを確認すること。
    - 参考画面↓
![IMG_0031.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472957/689f0250-6049-fff9-5e41-b41fa132ac41.jpeg)
5. 場合により、CDUIやSSHをDisableにしてログアウト。

セットアップは以上です。
# 最後に
検証環境の更改を機にESXiをセットアップしたところ、IntelCPUの機能追加？によりスムーズにセットアップできなかったため対応の流れをまとめました。
未だ12thより前のCPUを使用されている方も多いかと思いますし、IBM製品のみならずESXiは多くの仮想アプライアンスで利用されているため、今後の参考になれば幸いです。

# 参考情報
[Intel 12th、13thにESXiをインストールする方法](https://chibi-key.com/intel-12th13th%E3%81%ABesxi%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95)
→こちらの方の記事が大変参考になりました。
記事の内容ではESXi8系をセットアップされたパターンでした。今回の環境はESXi7でしたが、同様の方法で対処できました。
sshで古いシステムにログインできない時の対処法

# sshで古いシステムにログインできない時の対処法
原因は、新しいOpenSSHでSHA-1が制限されたため

## クライアントがAlmaLinux9の場合
以下ルート権限で

update-crypto-policies --set DEFAULT:SHA1
としたあとで
reboot

参考サイト
https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/9/html/security_hardening/proc_re-enabling-sha-1_using-the-system-wide-cryptographic-policies

## Ubuntu22.04の場合
以下ルート権限で
/etc/ssh/ssh_config をエディタで開く
Host *
と書かれている定義の最後に
    HostKeyAlgorithms=+ssh-rsa
    PubkeyAcceptedAlgorithms=+ssh-rsa
を追加することで、SHA-1が有効になる。

参考
https://pyopyopyo.hatenablog.com/entry/2022/11/02/180000
Mechanize でXpathをメソッドチェーンしたら一回目のatで絞り込んだはずの範囲以外を二回目に検索していた

```ruby:qiita.rb
page.at("//node[@class='class']")
    .search(%(//*[text()="text"]))
```

みたいな文でスクレイピングしてたとき、どうしても参照範囲がおかしいのを検証して見つけたのが、基準が分からないけどatで指定した場所以外からもsearchする現象。
残念ながらgemを調べるほどの能力がないのでto_htmlしたものをnokogiriでパースした。

```ruby:qiita.rb
node =page.at("//node[@class='class']").to_html

doc = Nokogiri::HTML(node)
doc.xpath('//*[text()="text"]').each do |link|
  puts link.content
end
```
NokogiriではなくてMechanizeに渡してもいいだろうがNokogiri単体のほうが軽いし良いだろう。
もっといいやり方募集
マイグレーションファイルのnull: false と モデルファイルの presence: true の違い、および スキーマ定義とバリデーション定義の比較

# マイグレーションファイルの`null: false` と モデルファイルの `presence: true` の違い、および スキーマ定義とバリデーション定義の比較

データベース設計とアプリケーションのデータ整合性の確保において、`null: false` と `presence: true` の違いは重要です。さらに、これらの概念をスキーマ定義とバリデーション定義と比較して理解しましょう。

## 1. `null: false` と `presence: true` の違い

### `null: false` (マイグレーションファイル)

- **関連性**: データベース設計に関連。
- **目的**: データベーステーブルの特定のカラムが「null」（空値）を許容しないことを指定。
- **例**: `t.string :name, null: false` は、`name` カラムが必ず値を持つことを保証。

### `presence: true` (モデルファイル - バリデーション)

- **関連性**: アプリケーションのモデルに関連。
- **目的**: モデルの属性（フィールド）に対して、フォームなどを通じてユーザーが提供するデータが「存在」しなければならないことを確認。
- **例**: `validates :name, presence: true` は、`name` 属性が空でないことを確認。ユーザーがフォームで名前を提供しない場合、バリデーションエラーが発生。

## 2. スキーマ定義とバリデーション定義の違い

### スキーマ定義

- **関連性**: データベース設計に関連。
- **目的**: データベースの構造を定義し、テーブル、カラム、データ型、制約、リレーションシップなどを指定。
- **適用範囲**: データベースの物理的な形式を決定。
- **例**: マイグレーションファイル内の `create_table` メソッドを使用してテーブルを作成し、`null: false` のような制約を指定。

### バリデーション定義

- **関連性**: アプリケーションのモデルに関連。
- **目的**: アプリケーションのモデルデータの整合性を確保。ユーザーが提供するデータが要件を満たすか確認。
- **適用範囲**: アプリケーションのデータ入力フォームなどから受け入れたデータに対して検証を行う。
- **例**: モデル内の `validates` メソッドを使用して、属性に関する条件を設定。`presence: true` などの条件を指定してデータの正当性を確認。

## まとめ

- `null: false` はデータベース設計の一部であり、テーブルのカラムが空でないことを指定します。
- `presence: true` はアプリケーションのモデル内でデータの整合性を確保するために使用され、ユーザーが提供したデータが存在することを検証します。
- スキーマ定義はデータベースの構造を定義し、バリデーション定義はアプリケーションのモデルデータの正当性を確認します。

これらの概念を理解することで、データベース設計とアプリケーションのデータ整合性をより効果的に管理できます。
成功踏上美國工作之路：海外工作及面試訣竅

在全球化的時代，越來越多的人夢想著能夠在國外工作，體驗不同的文化，拓展人生的視野。美國作為一個經濟強國和多元文化的國度，一直以來都是眾多尋求海外工作機會的人們的首選之地。但是，成功踏上[美國工作](https://www.apexcharity.org/news/3/85)之路需要不僅僅是勇氣，還需要準備充分的英文自我介紹和英文面試技巧。本文將探討如何在海外工作的過程中，克服語言和文化障礙，並提供一些實用的面試訣竅，幫助您實現職業夢想。

英文自我介紹的重要性
當您尋求海外工作機會，特別是在美國這樣的英語為主要工作語言的國家，一個出色的[英文自我介紹](https://www.apexcharity.org/news/3/92)是成功的第一步。這是您展示自己的機會，讓潛在的雇主了解您的背景、技能和動機。請確保您的自我介紹簡潔明瞭，包括您的姓名、教育背景、工作經驗和職業目標。不要忘記練習發音和口語流利度，這將幫助您在面試中留下深刻的印象。

[英文面試](https://www.apexcharity.org/news/3/93)的關鍵技巧
準備充分: 在面試前，研究公司和職位的相關信息，並準備回答常見的面試問題，如您的強項和弱點、為什麼選擇該公司等。這展示了您的專業性和對工作的熱情。

練習回答問題: 請找一位朋友或專業顧問幫助您模擬面試情境，並提供反饋意見。這有助於提高您的自信和表現。

尊重時間: 準時參加面試，這表現出您對工作的認真態度。同時，避免回答過於冗長的問題，以免耗盡面試官的耐心。

展現自信: 雖然面試可能會讓您感到緊張，但請嘗試保持冷靜和自信。良好的姿態和自信的言語表達能夠傳達出您是一位可靠的專業人士。

重視溝通技巧: 在英文面試中，良好的溝通至關重要。確保您的回答清晰、有條理，避免使用太多行話或俚語。

[海外工作](https://www.apexcharity.org/news/3/86)的過程
一旦您成功通過面試，就需要準備好應對移民和工作簽證程序。這涉及到繪制具體的計劃，包括辦理簽證、找到住宿、建立社交圈子等等。同時，您也需要了解當地的文化和生活方式，以更好地適應新環境。

總之，踏上美國工作之路可能是一個挑戰，但也是一個充滿機會的冒險。通過優秀的英文自我介紹和精湛的英文面試技巧，您可以提高成功的機會。同時，不要忘記在工作前做足功課，以確保在新的國度順利適應生活和工作。祝您在海外工作的道路上一切順利，實現職業夢想！
リーダブルコードをリーダブルにするぞ（その5）

## はじめに
こんにちは。
リーダブルコードの社内向け輪読会の資料です。
以下記事の続きです。

https://qiita.com/yo_ta/items/7b047a9815b7964119d1

今回は第Ⅲ部12-13章です。
前回から引き続き、コードに大きな変更を加える際のポイントを扱います。

## 第12章　コードに思いを込める
本章の冒頭で「ラバーダック・デバッグのことかな？」と思いながら読み進めたら、章末のまとめがやっぱりそうでした。

本章は、第10章で紹介された **「『このコードの高レベルの目標は何か？』と自問する」** という手法の詳細に当たると言えそうです。
自問する手順は以下の通りです。

```
「このコードの高レベルの目標は何か？」とうまく自問するための手順

1. コードの動作を簡単な言葉で同僚にもわかるように説明する。

2. その説明のなかで使っているキーワードやフレーズに注目する。

3. その説明に合わせてコードを書く。
```

手順1の「同僚」を「手元に置いたおもちゃのアヒルちゃん」に置き換えたものが、冒頭で触れた「ラバーダック・デバッグ」（本書では「ラバーダッキング」）と呼ばれるデバッグ手法です。

https://ja.wikipedia.org/wiki/%E3%83%A9%E3%83%90%E3%83%BC%E3%83%80%E3%83%83%E3%82%AF%E3%83%BB%E3%83%87%E3%83%90%E3%83%83%E3%82%B0

自分の書いたコードを1行ずつ、アヒルちゃんでも理解できる言葉でアヒルちゃんに向かって説明することで、「このコードで自分が実現したいのは何か？（高レベルの目標は何か？）」を客観的に整理します。

その後、手順2で高レベルの目標と下位問題を改めて整理し、手順3で下位問題を抽出することで、ソースを改善します。

## 第13章　短いコードを書く
本章では、なるべくコードを書かないこと、小さいコードで済ますことを念押ししています。

### 要点
#### 13.1, 13.2 なるべく小さい実装コストでなるべく大きなメリットを出すことの要点
無闇に高機能なコードを書く必要はないし、精度や速度を追求しすぎる必要はありません。
1/4の実装コストで問題の半分を改善できるなら十分。

#### 13.3, 13.4 コードを小さく保つことの要点
プロジェクトが進行してコード量が増えて「重く」なると、コードの全貌を把握するのが困難になり、機能追加のための実装コストや心理的抵抗感が跳ね上がってしまいます。
そのため、コードをできるだけ小さく軽量に維持しなければなりません。

```
コードを小さく保つための要点

- 共通コードを作って重複を削除すること

- 不必要な機能やコードを削除すること

- プロジェクトをサブプロジェクトに分割すること

- コードの「重量」を意識し、コードを軽く機敏に保つこと

- 標準ライブラリに慣れ親しんで活用すること

- ライブラリを再利用すること
```

## おわりに
総じて、当たり前のことをきちんとやり続ける重要性を説く章という印象でした。それがなにより難しい。

次回もリーダブルにしていきます。

（参考文献）Dustin Boswell,Trevor Foucher.リーダブルコード より良いコードを書くためのシンプルで実践的なテクニック,講談社,2012,237p.
Railsでログアウトボタンを作成する際のHTTPメソッド変更

## Railsでログアウトボタンを作成する際のHTTPメソッド変更

Railsでログアウトボタンを実装する場合、通常は`link_to`ヘルパーメソッドを使用します。ログアウトの操作はセッションを削除するアクションとして、HTTPメソッドとしては`DELETE`が適しています。しかし、`link_to`ヘルパーメソッドはデフォルトでHTTPメソッドが`GET`に設定されています。そのため、HTTPメソッドを`DELETE`に変更する必要があります。これはTurboフレームワークを使用する場合に特に重要です。

### 1. ログアウトボタンの作成

まず、ログアウトボタンを作成します。通常、`link_to`ヘルパーメソッドを使用して次のように記述します。

```erb
<%= link_to 'ログアウト', logout_path %>
```

### 2. HTTPメソッドの変更

`link_to`ヘルパーメソッドを使用する場合、HTTPメソッドを変更する必要があります。これはTurboフレームワークの仕様に合わせたものです。ログアウトアクションを`DELETE`メソッドに変更するため、以下のように記述します。

```erb
<%= link_to 'ログアウト', logout_path, method: :delete, data: { turbo_method: :delete } %>
```

このコードのポイント：

- `method: :delete`：これにより、HTTPメソッドが`DELETE`に設定されます。
- `data: { turbo_method: :delete }`：Turboフレームワークのために、HTTPメソッドを`DELETE`に指定します。

### 3. ログアウトアクションの設定

ログアウトボタンを機能させるには、コントローラーにログアウトアクションを設定する必要があります。通常、`SessionsController`などのコントローラー内でセッションを削除するアクションを作成します。

```ruby
def destroy
  reset_session
  redirect_to root_path, notice: 'ログアウトしました'
end
```

このアクションはセッションをリセットし、ユーザーをログアウト状態にします。

ログアウトボタンが正しく設定されている場合、ユーザーがクリックするとセッションが削除され、ログアウトが実行されます。

以上の手順に従うことで、Turboフレームワークと共にRailsでログアウトボタンを作成し、HTTPメソッドを`DELETE`に変更することができます。これにより、セキュアなログアウト機能を実現できます。
requirements.txtのpipコマンド一覧

venvにパッケージを取り込む際に、いくつかのpipコマンドを利用したのでまとめます。

https://docs.python.org/ja/3/library/venv.html

# requirements.txtからパッケージを一括インストール
```
pip install -r requirements.txt
```

# インストール済みパッケージ確認
```
pip list
```
<br>
<br>
一旦、キャッシュを削除したり、アンインストールしたい場合は、以下のコマンドを使用します。

# キャッシュ削除
```
pip cache purge
```

# アンインストールするパッケージ一覧のファイル作成
```
pip freeze > uninstall.txt
```

# パッケージのアンインストール
```
pip uninstall -y -r uninstall.txt
```
【ChatGPT無】に“老害社員”への対処法を尋ねてみた。


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

　今回は、“老害社員”への対処法を尋ねてみました。

:::note info
本記事は、ChatGPT（無料版）で
行なっております。GPT4での確認
はできておりません。あしからず。
:::
　今回は、
　　Yahooニュースの
[「話聞かない・仕事しない・責任取らない」職場に“老害社員”が増加中？50代以上の社員が慕われない理由とは](https://news.yahoo.co.jp/articles/ff5d258914d3b4283cec11c01b766955217844c7)
　　　を読んで、思い付きました。

　ちなみに、この記事には、
　　酒場でのタイプ別の対処法が
　　　書かれていますので、
　　　　参考にしてください。
　　　　　まぁ、対処は大変ですがw
***
　老害とは、何か？
　　goo辞書では
「ろう‐がい〔ラウ‐〕【老害】 の解説
企業や政党などで、中心人物が高齢化しても実権を握りつづけ、若返りが行われていない状態」

　うわっ、高齢化会社！

　GoogleSGEは
***
「老害」とは、周囲に迷惑をかける高齢者を指す表現です。組織や社会で幅を利かせすぎて言動が疎まれる高齢者、あるいは、傍若無人な振る舞いによって若者に必要以上の負担や迷惑をかけている高齢者などを指します。﻿
「老害」の語は、もともとは組織の世代交代・新陳代謝を阻む高齢層といった意味が主流だったといえます。企業や政治の中心にある人たちの高齢化を批判し、若返りの必要性をこめていう語です。﻿
「老害」は、特に若い人の間で使われる言葉です。以前は高齢の政治家が不適切な発言をした場合によく使われる言葉でしたが、最近の論調では対象となる年代が70代以上のシニア層だけでなく50～60代のエルダー層に拡大しており、より広い分野で一般的に使われる言葉になっています。﻿
「老害」は、権威的にふるまう既存世代を指す言葉ですが、必ずしも高齢者だけが該当するわけではありません。﻿
***
　だいたい
　　合ってますねw
***
　さて、
　　ChatGPTさんに
　　　尋ねてみます。
***
***User***
老害をご存知ですか？
知らなければ、知らないと答えてください。

***ChatGPT***
申し訳ありませんが、"老害"という言葉についての具体的な情報は提供できません。詳細を教えていただけると助けになるかもしれません。

***User***
老人がおよぼす被害のことです。

***ChatGPT***
了解しました。"老害"は、老人が他の人々に対して引き起こす様々な被害やトラブルを指す言葉のようです。老人による被害の具体的な例や状況について質問がある場合、お知らせいただければお手伝いできるかもしれません。

***User***
こうした老害をなんとかしたいのですが、何か方法はありませんか？
ちなみに、老害を起こしているのは、50代から定年間際の上司（社長も含む）です。
わからなければ、わからないと答えてください。

***ChatGPT***
老害に対処する方法は、具体的な状況や個人によって異なります。一般的なアドバイスとして、以下のようなアプローチが考えられます：

1. コミュニケーション: 上司や関係者とオープンな対話を持ち、問題を共有しましょう。適切な方法で問題点を伝え、解決策を模索します。

2. 上司への提案: 具体的な提案を上司に提供し、改善の機会を提供できます。課題の改善に向けたアイデアを共有しましょう。

3. 人事部門への相談: 会社の人事部門に相談し、問題を報告することも考えられます。人事部門は適切な対処方法を提供することができます。

4. 助言を求める: 専門家やカウンセラーから助言を受けることも有用です。専門家は効果的な対処策を提供できます。

5. 組織内のサポートを受ける: 同僚や部下と連携し、共同で問題に対処する方法を検討します。

ただし、状況や文化によって最適な対処方法が異なるため、具体的なアドバイスは状況に応じて調整されるべきです。また、法的な規定や会社のポリシーにも留意する必要があります。

***User***
上司は、人の仕事にケチを付け、それに対応して失敗すると、責任逃れして、我関せずの態度です。

***ChatGPT***
そのような上司の行動は、労働環境に対して非常に有害である可能性があります。この状況に対処する際に考慮すべきいくつかのステップがあります：

1. 証拠を集める: 上司の行動についての具体的な証拠を収集しましょう。不適切な行動やコミュニケーションの記録、メールやメモなどが役立つでしょう。

2. 言葉で対処する: 上司に対して、彼らの行動が問題であることを明確に伝えましょう。具体的な事例や証拠を示し、協力的な改善を求めます。

3. 上司の上司と相談: 直接の対話が効果がない場合、上司の上司や人事部門と相談することが重要です。問題が解決する可能性が高まります。

4. 労働法の遵守: 不適切な行動やパフォーマンスに関する法的な懸念がある場合、労働法の専門家と協力することが重要です。

5. 組織外の支援を考える: 労働組合や労働者の権利を守る非営利団体など、組織外の支援を受けることも検討してください。

6. 自己保護: 自分自身のメンタルヘルスとストレス管理に注意を払い、適切なサポートを受けましょう。 

このような状況に対処するのは難しいことかもしれませんが、適切な対処法を追求することで改善の可能性があります。
***
　具体的な手順が
　　示されましたね。

　ここで
　　私からの助言。

　証拠を集めたら、
　　直接対決をしては
　　　いけません。

　同一被害者を集め、
　　上司の上司（社長とか）と
　　　老害社員、
　　　　できれば、
　　　　　第三者の有識者を
　　　　　　入れての追求が
　　　　　　　望ましいでしょう。

　一対一は、
　　相手を助長させる
　　　可能性がありますし、
　上司の上司に訴えても
　　有耶無耶になる
　　　可能性もあります。

　そこで、
　　同一被害者を集め、
　　　証拠をまとめ、
　　　　第三者を含めた場で
　　　　　訴えるのです。

　第三者の存在は、
　　ことを有耶無耶に
　　　させないためです。

　外部の存在は、
　　上司や上司の上司に
　　　ことの重大さを
　　　　理解させることにも
　　　　　つながります。

　これで
　　改善しないならば、
　　　もうその会社には
　　　　未来はない、と
　　　　　諦めて、退社を
　　　　　　検討しましょう。

　会社と
　　あなたの
　　　相性が悪いのですから。

　人には、
　　我慢の限界
　　　というものが
　　　　ありますから。
***
　退職者が多い会社には、
　　老害社員がいるのかも。

　今回は、ここまで。
M1Macでtfenv install 0.14.8ができなかった件

# 背景
ZOZOではAWS以外のリソースは基本的にTerraformで管理しています。例えば、Datadogのアラートやダッシュボード、Sentry、PagerDutyなどです。
現状、それぞれのリソース作成に使用しているTerraformのバージョンが異なる状態になっているため、ローカルのPCでも複数のTerraformのバージョンを管理できるようにする必要があります。
そのような場合に役立つのが[tfenv](https://github.com/tfutils/tfenv)です。

# tfenv入門
tfenvはTerraformのパッケージマネージャーです。複数のTerraformのバージョンを簡単に管理できます。

```
# ローカルで使用可能なバージョン一覧を表示する
~% tfenv list
* 1.3.9 (set by /opt/homebrew/Cellar/tfenv/2.2.3/version)
  1.2.7
  1.0.11
  1.0.10
  0.14.11
  0.14.8

# ローカルのTerraformのバージョンを表示する
~% terraform version
Terraform v1.3.9
on darwin_arm64

# リモートでインストール可能なバージョン一覧を表示する
~% tfenv list-remote
1.7.0-alpha20231130
1.7.0-alpha20231108
1.7.0-alpha20231025
1.6.5
...

# 1.6.5をinstallする
~% tfenv install 1.6.5
Installing Terraform v1.6.5
Downloading release tarball from https://releases.hashicorp.com/terraform/1.6.5/terraform_1.6.5_darwin_arm64.zip
############################################################################################################################################################################################################################## 100.0%
Downloading SHA hash file from https://releases.hashicorp.com/terraform/1.6.5/terraform_1.6.5_SHA256SUMS
No keybase install found, skipping OpenPGP signature verification
Archive:  /var/folders/th/xllm4jmn2_j5b2c6wxp4rg280000gn/T/tfenv_download.XXXXXX.UbWOfqKS/terraform_1.6.5_darwin_arm64.zip
  inflating: /opt/homebrew/Cellar/tfenv/2.2.3/versions/1.6.5/terraform
Installation of terraform v1.6.5 successful. To make this your default version, run 'tfenv use 1.6.5'

# 1.6.5に切り替える
~% tfenv use 1.6.5
Switching default version to v1.6.5
Switching completed

# ローカルのTerraformのバージョンを表示する
~% terraform version
Terraform v1.6.5
on darwin_arm64
```

# 問題
本題です。
tfenvで `0.14.8` をinstallしようとしたところ、以下のエラーになりました。

```
$ tfenv install 0.14.8
Installing Terraform v0.14.8
Downloading release tarball from https://releases.hashicorp.com/terraform/0.14.8/terraform_0.14.8_darwin_arm64.zip
curl: (22) The requested URL returned error: 404

Tarball download failed
```

たしかに、出力されているURLにいってみると、該当のファイルは存在しませんでした。
https://releases.hashicorp.com/terraform/0.14.8/terraform_0.14.8_darwin_arm64.zip

原因は、armは1.0.2からの対応だからのようです。ローカルPCはM1 Macです。
https://reeases.hashicorp.com/terraform/1.0.2

# ワークアラウンド
Terraformのバージョンを1.0.2に上げるのが根本的な解決ですが、 `TFENV_ARCH=amd64` をつけてコマンドを実行することで、この問題を回避することができました。

```
$ TFENV_ARCH=amd64 tfenv install 0.14.8
```
ZOZOのバックエンドエンジニアがSREにジョブチェンするまでの話

# はじめに
2023年度4月より、社内の異動を通じて、職種をバックエンドエンジニアからSREにジョブチェンしました。
同じような挑戦をしている方、検討している方の参考になれば幸いです。

# これまでの経験
ZOZOではバックエンドエンジニアとして約4年間働いてきました。最初の一年半は、Go言語で新規事業のバックエンド開発をしました。残りの二年半は、Go言語でZOZOTOWNのマイクロサービス開発をしました。
前職でOpenStackやAnsibleなどを使ったインフラ系の業務経験はありましたが、SREとしての実務経験はなく、パブリッククラウドやKubernetesの経験もありませんでした。

# 異動先
## 組織
「プラットフォーム基盤SRE」という組織に異動しました。
この組織は、マイクロサービスプラットフォームのプロビジョニングとオペレーションの自動化に責任を持ちます。信頼性の高い基盤を土台として、ZOZOTOWNの開発者とSREの成果創出をサポートおよび促進し、ZOZOTOWNの成長を高速前進させることがミッションです。

## 業務内容の例
- マイクロサービスのインフラ構築と保守
- 監視・アラートの設定と保守
- CI/CDの構築と保守
- 負荷試験
- 障害試験
- 運用業務（Upgrade系の業務、問い合わせ対応、アラート対応、事前スケーリング作業、定期作業など）
- etc

基本的にIaC化されているので、それの実装や検証、社内コミュニケーション、ドキュメント作成などが主な仕事です。

## 技術スタック
Docker/Kubernetes(EKS)/kustomization/Istio/Flagger/Flux/AWS/CloudFormation/Terraform/Datadog/Sentry/Pager Duty/GitHub Actions/GitHub/Gatling

# SREへジョブチェンするまで
## 経緯
上司との1on1で、自ら異動を希望しました。
ありがたいことに、残念がっていただきましたが、CTOまで話がいき、スムーズに異動の話が進みました。
将来的にはバックエンドに戻る意思が高かったのですが、最低2年間はお世話になりたいというお話をさせていただきました。SREとして一人前になり、その恩返しをするためには、2年間は必要だろうという計算でした。未経験かつ期限付きで受け入れていただいたSRE部には本当に感謝しております。

## ジョブチェンの理由
大きく2つあります。
1つ目は、バックエンドエンジニアに加えて2つ目の専門性を身につけることで、ソフトウェアエンジニアとしてより強くなれると思ったからです。バックエンドの経験はSREでも役立つと思いますし、その逆も然りだと思います。将来的にバックエンドエンジニアに戻っても、SREでの経験がシステムの要件定義や設計、実装、試験、リリース、運用業務、CI/CDの構築と保守、社内コミュニケーションなどの様々な場面で役立つと思っています。
2つ目は、バックエンドエンジニア以外としても働けたという自信を自分の中で持つためです。この自信により、将来への心理的安全性を手に入れたかったです。極端にいうと、バックエンドエンジニアが不要という世の中（現実的に直近でなるとは思いませんが）になったとしても、他の職種で食べていけるという心の余裕みたいなものが欲しかったです。また、重要なのはバックエンドエンジニアやSREなどの特定の職種でなく、「ジョブチェンをして苦しみながらも頑張って勉強してキャッチアップして、その職で一人前になる。」という経験をしたかったです。

## なぜSREか？
ソフトウェアエンジニアとしての選択肢としては他に、フロントエンド、ネイティブアプリ、MLなどの分野があると思います。
フロントエンドの開発は個人的に苦手で、ネイティブアプリの開発はもっと苦手（というよりも経験が一切ない）で、MLは学生時代に少しかじった程度であり、いずれも自分にはマッチしなそうでした。
SREは前職でインフラの経験が少しあったのでその経験を活かせると思ったのと、バックエンドとの親和性が比較的高そうだと感じました。

## なぜプラットフォーム基盤SRE？
プラットフォーム基盤SREは、自分が開発担当していたマイクロサービス（zozo-api-gateway、認証サービス、会員サービス）を管理しているチームであり、自分が開発に携わったマイクロサービスを今度はSREとして担当してみたいと思ったからです。また、マイクロサービスの知識はSREメンバーよりも深いため、その点でのGIVEをチームや会社にできると考えたためです。
また、バックエンドエンジニア時代からプラットフォーム基盤SREのメンバーとは業務上でのコミュニケーションが多くあったので、人間関係もうまくいきそうだと容易に想像できたからです。

## なぜこのタイミング？
ようやく、バックエンドエンジニアとしてある程度の高い水準で仕事ができるようになったという自己評価を得たからです。
そして、新しいことにチャレンジするならば、なるべく若いうちが良いと思ったからです。（年齢は30前半です。）

## 異動までに準備したこと
- [Kubernetes完全ガイド](https://amzn.asia/d/6fboRIA)を少なくとも5週は読みました。
- [Kubernetes on AWS ~アプリケーションエンジニア 本番環境へ備える](https://amzn.asia/d/cpUeLAk)を読みました。
- CKADを取得しました。
  - 「上記の本を読んでなんとなく知識はついたけど手が動かない。」という感じだったので、ハンズオン形式で勉強ができるCKADがかなり役立ちました。
  - [技術メモ](https://qiita.com/gold-kou/items/0843ce90e215570a980d)も書きました
- CloudFormationとEKSテンプレートのサンプル実装をしました。
  - https://github.com/gold-kou/cfn-practice
- 以下のIstioのYoutubeの動画を見たり、[公式ドキュメント](https://istio.io/latest/docs/)を読みました。
	- https://www.youtube.com/watch?v=16fgzklcF7Y
	- https://www.youtube.com/watch?v=9nN3PsPig2g
	- https://www.youtube.com/watch?v=0sEBPh59LqI&t=930s
- Flaggerの[公式ドキュメント](https://docs.flagger.app/)を読みました。
- 社内のGitHubリポジトリや資料を覗いて、実プロダクトでのk8s、CFn、Istio、FlaggerのYAMLを異動前に分かる範囲で予習しておきました。

# ジョブチェンしてみてどうだったか
明日の記事にて未経験の自分が具体的にどんな業績をあげられたか、ジョブチェンしてみてどうだったかを記事にしています。
ぜひ、明日も読んでください。

# We are hiring
もし興味あれば、ぜひ採用リンクからご応募ください！
https://hrmos.co/pages/zozo/jobs/0000247
[Vue.js] 迷いやすいv-modelの修飾子を3行で。

## v-model.lazy
inputイベントではなくchangeイベントに反応する。
例えばinput type=“text”では、文字が入力し終わってから変化する。

## v-model.number
入力された値がNumber型になる。
inputは入力された値は常に文字列型になるため、数値型にしたい場合。
（ちなみにhtmlでinput type=“number”としてもデータ型としては文字列だから注意）

## v-model.trim
ユーザーから入力された値の両端の空白を削除する。
JSの.trim()と同じ。
【GoogleSites】新しいGoogleSitesのアクセス権制御方法

# GoogleSitesとは
Googleが無料で提供している情報共有サイト作成アプリです。
簡単にホームページを作成することが可能で、社内の情報共有ツールなどに使用されています。
豊富なテンプレートや設定項目が用意されており、Googleのコンテンツなどを自由に配置できることが特徴です。

# 前提
GoogleSitesを使用して会社の掲示板を作成します。
以前は掲示板内の各ページごとに異なるアクセス権限を設定することが可能でしたが、新しいGoogleSitesのバージョンではこの機能が利用できなくなりました。
この問題に対処するために、サイトを分けて、各GoogleSitesの保管場所を変更し、閲覧できるユーザーを制限する方法で掲示板を作成します。

会社の構成は以下の仮定に基づいています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516839/ca1d9e68-d87e-b7b7-ccbe-9bf29b8c0c24.png" width=50%>

# 構成例
Googleドライブ上に異なる階層のフォルダを作成し、それぞれのフォルダに権限を設定します。
これにより、各階層ごとに異なるユーザーグループや個々のユーザーにアクセス権を付与することが可能になります。

**フォルダ構成**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516839/44eb0390-8cf3-e388-2254-ff45243d50e4.png" width=50%>
**画面遷移**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516839/cd1a9d1b-bcbe-24df-0fba-c76f44f7e119.png" width=50%>

# 権限の設定方法
GoogleSitesを保管するフォルダに対して権限の設定を行います。

①権限を付与するフォルダの「共有」ボタンを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516839/a9c19c5c-4218-3d7a-1c13-2ad7d651a823.png)

②グループやユーザーを追加して「完了」を押下します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516839/8ec39b97-fbe8-d188-54cd-4b4a47ef57b8.png" width=40%>

# サイトの編集方法
### 各掲示板へのリンク追加方法
#### 例）「全社共通掲示板」⇔「本社掲示板」
**全社共通掲示板**
①「ページ」タブの「新しいリンク」を押下します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516839/22a3d0e4-7228-d73f-55d5-745cd9bb1fe3.png" width=90%>

②名前と遷移先（本社掲示板）の公開後のリンクを入力し、「完了」を押下します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516839/56e2837b-7b00-91ca-eb36-95c0c0b93633.png" width=20%>

アクセス権が付与されているユーザーは、「全社共通掲示板」から「本社掲示板」にアクセスできるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516839/c1659d19-2732-a392-8b92-ba957db272a1.png)

### 各詳細情報へのリンク追加方法
#### 例）「営業第１掲示板」「営業第２掲示板」
**営業第１掲示板**
①「営業第１」のユーザーに表示したい情報を記載します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516839/9c68357f-a675-3eab-6ba0-d0b163270a7e.png" width=80%>

②①で記載した情報の見出しのリンクをコピーします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516839/e0759cf1-4f18-9fcb-51d6-29b407f116ac.png)

**営業部掲示板**
⓷情報の見出しと、②でコピーした「遷移先の詳細情報の見出しのリンク」を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516839/60c9ba8a-9170-4ccb-3342-b8869f7e6a9f.png)

営業部の掲示板には、「営業第１」「営業第２」の情報が表示されますが、詳細情報は別のサイトに分けて掲載することで、各メンバーのみが閲覧できるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516839/88d9c965-f157-4f32-aac0-7e33659d67e6.png)


# さいごに
ページごとに権限を設定することはできなくなりましたが、この方法を用いることで、掲示板全体のセキュリティを管理し、特定のユーザーだけに特定のページを閲覧させることができました。
no such file or directory: '/usr/local/lib/libpng16.a'

## こんな時どうする

M2 Macで `npm install`　した際にエラーが出た
```zsh
npm ERR! clang: error: no such file or directory: '/usr/local/lib/libpng16.a'
```

## インストール済みのlibpngの情報を確認

```zsh
brew info libpng
==> libpng: stable 1.6.40 (bottled), HEAD
Library for manipulating PNG images
http://www.libpng.org/pub/png/libpng.html
/opt/homebrew/Cellar/libpng/1.6.40 (27 files, 1.3MB) *
  Poured from bottle using the formulae.brew.sh API on 2023-11-01 at 09:13:47
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/lib/libpng.rb
License: libpng-2.0
==> Options
--HEAD
	Install HEAD version
==> Analytics
install: 87,440 (30 days), 286,007 (90 days), 722,366 (365 days)
install-on-request: 5,011 (30 days), 15,346 (90 days), 35,485 (365 days)
build-error: 20 (30 days)
```
→バージョンは `1.6.40` 

## シンボリックリンクを作成
```zsh
# ディレクトリが無ければ作成
sudo mkdir -p /usr/local/lib

# シンボリックリンク作成
sudo ln -s /opt/homebrew/Cellar/libpng/1.6.40/lib/libpng16.a /usr/local/lib/libpng16.a
```
XcodeからApp Store Connect の Test Flight へ アーカイブをアップロードする方法

## Xcodeを用いて直接TextFlight へアップロードする方法

### 1. Xcodeプロジェクトを開く:
Xcodeを起動し、アプリのプロジェクトを開く。

### 2. ビルド設定の確認:
プロジェクトを開いたら、`Runner`の`Target`を開いてアプリのビルド設定を確認します。設定が正しいことを確認してください。

### 3. アーカイブの作成:
Xcodeメニューの "Product" > "Archive" を選択して、アプリのアーカイブを作成します。アーカイブはビルドされたアプリのバイナリファイルです。

### 4. アーカイブの管理:
""Window" > "Organizer"を開いて、作成したアーカイブを管理します。これは、Xcodeメニューの "Window" から "Organizer" を選択してアクセスできます。

### 5. アップロード:
Organizerで、作成したアーカイブを選択し、"Distribute App" ボタンをクリックします。

### 6. 配布オプションの選択:
配布オプション画面で、"App Store Connect"を選択し、"Next"をクリックします。

### 7. App Store Connectアカウントへのサインイン:
Apple IDと関連づけられたApp Store Connectアカウントにサインインします。

### 8. アーカイブの選択:
アーカイブファイルを選択し、"Next"をクリックします。

### 9. プロビジョニングプロファイルの選択:
適切なプロビジョニングプロファイルを選択し、"Next"をクリックします。プロビジョニングプロファイルはアプリの署名に使用されます。

### 10. アップロード:
アーカイブファイルをApp Store Connectにアップロードするために、必要な情報を入力します。これには、バージョン情報、スクリーンショット、App Store Connectでの詳細な設定などが含まれます。必要な情報を入力し、"Next"をクリックします。

### 11. リリース:
最後に、アプリをTestFlightにリリースするために必要な情報を入力し、"Upload"をクリックします。これにより、アーカイブファイルがApp Store Connectにアップロードされ、TestFlightベータテストに提供されます。

----
参考記事
https://developer.apple.com/help/app-store-connect/manage-builds/upload-builds
PowerAutomateでTeams操作がしたい！

## この記事で伝えたいこと
:::note info
順当に、Teamsのコネクタを使おう
メンバーの削除は**Teamsのコネクタにはない**のでOffice 365 Groupsのコネクタを使おう
:::
~~自分で発見したことだけどググったらすぐにでてくるような情報でした。ただのアウトプットだと思って許して~~

## 本題
早速ですが、PowerAutomateでTeamsの操作したいこと、ありますよね。
そんな時にまさにこれ、といったコネクタがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676003/b9167376-1af0-38fb-994e-4d64dab7bbcb.png)
(画像では写っていませんが、まだ下の方に続いて他にもアクションが多数あります。)

チャネルに何かメッセージを投稿したり・・・チームからメンバーの追加等が行なえます。

## 注意点
なんだか、この流れだといかにもチームからメンバー削除もたやすく行えるように見えますよね？
ですが・・・Teamsのコネクタだと**削除ができない**、というよりそもそも**アクションが存在しません。**

えっ、と思いましたよね。筆者も思いました。

じゃあどうするの？といったとこですが・・・。次で触れたいと思います。

## 解決策
Office 365 Groupsのコネクタを使いましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676003/f25a1ea7-a43b-ff18-0d65-4717c6788643.png)

Office365グループとありますが、Microsoft365グループと言う認識で問題ないです。
Office365というのは、過去の名残のようですね。

TeamsのチームはMicrosoft365グループと実質的に繋がっているので、Microsoft365グループから削除するとTeamsのチームからも削除される、という寸法です。

画像にあるように、メンバー追加もでき、実質的にTeamsのチームにメンバー追加も行えてしまいます。
これに関しては話がそれてしまうので深くは触れませんが...HTTP 要求 V2を送信する、というアクションを使うことでGraph APIを使用することもできます。

:::note warn
そもそもどうやら、Microsoft365アカウント(職場アカウント)というのと、Microsoftアカウント(個人アカウント)があるらしく・・・もしかしたらOffice「365」とあるので個人でつかない、とかあるかもしれません。
こちらについては**未検証**です。すみません。
:::

## ポエム
ここからは完全に余談で関係ない話なので、読んでも読まなくてもよいです。

また、ポエムすぎるので消せ、という依頼があれば削除します。

なんだか、前回の投稿から2ヶ月近く空いてしまいました。
なんか、プライベート含め仕事もそうですが意欲が完全に下がり切っていました。
具体的に何か嫌なことがあったとか、そういうわけではないんですが完全にやる気が出ませんでした。
(嫌なことがなかったかと言ったら嘘だけど・・・)

あんまりPowerAppsとかその辺触る機会が減って記事ネタがないのももちろん有りましたが・・・
まあ、ともかくリハビリがてらではないですが・・・短めでいいから何か記事を書こうと思いたったわけでした。

## 参考
https://learn.microsoft.com/ja-jp/power-automate/teams/send-a-message-in-teams
Stirlingで構造体編集

# 概要
バイナリエディタStirlingで構造体編集、やってみた。
bmpファイル、読んでみた。

# Stirling構造体に使える型


|型名	|サイズ|		Stirling構造体編集時の値
|:--|:--|:--|
|BYTE	|１バイト	|１６進表記
|byte	|１バイト	|符号なし１０進表記
|CHAR	|１バイト	|符号付き１０進表記
|WORD	|２バイト	|１６進表記
|word	|２バイト	|符号なし１０進表記
|SHORT	|２バイト	|符号付き１０進表記
|DWORD	|４バイト	|１６進表記
|dword	|４バイト	|符号なし１０進表記
|LONG	|４バイト	|符号付き１０進表記
|float	|４バイト	|単精度浮動小数点数
|double	|８バイト	|倍精度浮動小数点

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/08c57ebe-acc8-d054-f64c-b1d71d59deaa.png)

# BITMAP256_SAMPLE構造体

```
struct RGBQUAD {
	BYTE	rgbBlue;
	BYTE	rgbGreen;
	BYTE	rgbRed;
	BYTE	rgbReserved;
};

struct BITMAPFILEHEADER {
	WORD	bfType;
	DWORD	bfSize;
	WORD	bfReserved1;
	WORD	bfReserved2;
	DWORD	bfOffBits;
};

struct BITMAPINFOHEADER {
	DWORD	biSize;
	LONG	biWidth;
	LONG	biHeight;
	WORD	biPlanes;
	WORD	biBitCount;
	DWORD	biCompression;
	DWORD	biSizeImage;
	LONG	biXPelsPerMeter;
	LONG	biYPelsPerMeter;
	DWORD	biClrUsed;
	DWORD	biClrImportant;
};

struct BITMAPINFO {
	BITMAPINFOHEADER	bmiHeader;
	RGBQUAD				bmiColors[256];
};


struct BITMAP256_SAMPLE {
	BITMAPFILEHEADER	FileHeader;
	BITMAPINFOHEADER	bmiHeader;
	RGBQUAD				bmiColors[256];
};

```

以上
laravel APIのレスポンスで配列の中にオブジェクトを入れた配列をJSON化したら空のオブジェクトが返されてしまう（jsonSerialize）

## 概要

- APIの実装中に「配列の中に入った連想配列」をレスポンスで返したかったが、「連想配列」をオブジェクトの状態でJSON化したら、レスポンスが意図したものにならなかった。

## 前提

- 下記のようなJSONレスポンスを返したかった。

    ```json
    "histories": [
        {
            "id": 3,
            "user_id": 3,
            "description": "hoge fuga",
        },
        {
            "id": 4,
            "user_id": 3,
            "description": "foo bar",
        }
    ],
    ```

- 下記の様にJsonResourceを使って返そうと思い実装した。

    ```php
    /** @var array<int, HistoryObject>
    $histories = getHistories(); // ログイン中のユーザーIDを使ってusersとのリレーションがあるhistoriesテーブルのレコードを複数取得する。レスポンスは事情によりHistoryの情報が入ったオブジェクト（HistoryObject）が返される。
    return [
        'histories' => $histories;
    ];
    ```

## 問題発生

- テストコードを走らせると下記のようにレスポンスが返ってることがわかった。

    ```json
    "histories": [{}]
    ```

- 中身が空で返ってる。

## 原因

- JSONへの変換は、配列か、オブジェクト（プロパティがpublicである or JsonSerializableインターフェースが実装されている）ものだけ対応している。
- 今回のHistoryObjectはプロパティはすべてprivateでJsonSerializableインターフェースで定義されているメソッドも実装されていない。
- 今回空でレスポンスが返ってしまったのは「JsonSerializableインターフェースが定義されていないね、じゃあpublicなプロパティはあるかな？ないね、空オブジェクトをレスポンスで返すよ」ということだった。

# 解決方法

- 今回はJsonSerializableインターフェースをimplementsし、jsonSerializeメソッドを実装することで問題を解決しようと思う。他には下記のような解決策があるかも。
    - HistoryObjectのプロパティをpublicにする。
    - コントローラーかどこかでHistoryObjectのプロパティを配列に直す。
- HistoryObjectのクラスに`implements JsonSerializable`をしたあと、下記の様なメソッドを実装した。

    ```php
    /**
     * JSON形式にシリアライズする際に呼ばれる
     * どのようにJSON形式に変換するかを定義
     * 本クラスが配列で返されるため、このような定義が必要
     *
     * @return array<string, string|int|null>
     */
    public function jsonSerialize(): array
    {
        return [
            'id' => $this->id,
            'userId' => $this->userId,h,
            'description' => $this->description,
        ];
    }
    ```

- 上記の実装をしたところ、その他のコードは変更せずとも期待する下記の値が返された。

    ```json
    "histories": [
        {
            "id": 3,
            "user_id": 3,
            "description": "hoge fuga",
        },
        {
            "id": 4,
            "user_id": 3,
            "description": "foo bar",
        }
    ],
    ```
FirebaseAnalyticsのDebugViewで実機のAndroid端末が表示されない時にやったこと　

## やりたかったこと
FirebaseAnalyticsのDebugViewでログをリアルタイムで取得したかったが、
デバッグに使用するデバイスのところにデバイスが表示されなかった。

## 直接の原因

__<font color="Red">広告ブロッカーをつけていた</font>__

私のAndroidではAdGuardを使用していたのですが、AdGuardをつけている状態だと`デバッグに使用するデバイス`に表示されないようです...(ログ自体も送信されない?)

## 他に注意すること
結局、広告ブロックが原因だったのですが、もうひとつミスってたことがあったので書き残しておきます。

### adbコマンドが間違っていないか
androidでログを送信する際には、以下のadbコマンドを打つ必要があります。

```
adb shell setprop debug.firebase.analytics.app パッケージ名
```

パッケージ名を間違えていてもエラーなどはでないため、注意が必要です。

adbコマンドを打った後、再起動する必要があるのも注意です。
OprnAI GPT-3.5-turbo APIを使用したchatbotを作成

このプロジェクトでは、OpenAI GPT-3.5-turboを利用して、一般的な対話を行うchatbotを実装する。

# 必要な環境
-Python 3.8以上
-OpenAI Pythonライブラリ
-python-dotenvライブラリ
-OpenAI APIキー

# インストール
1,リポジトリをクローンまたはダウンロードする。
```
git clone https://github.com/yourusername/project.git
```
2,必要なパッケージをインストールする。
```
pip install openai python-dotenv
```
# 使用方法
1,.envファイルを作成し、以下のようなOpenAI　APIキーを設定する。
```
OPENAI_API_KEY=your-api-key
```
2,chatbotにリクエストを送信する。
```python
import os
import openai
from dotenv import load_dotenv

load_dotenv(override=True)
load_dotenv(".env")

OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
openai.api_key = OPENAI_API_KEY

response = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",
    messages=[
    {
        "role": "user",
        "content": "あなたの質問"
    },
    ],
)
```
3,レスポンスを表示します。
```python
print(response.choices[0]["message"]["content"].strip())
```
# 注意
このコードは、APIキーを .env ファイルから取得し、ソースコードからAPIキーを除外しています。これは、APIキーなどの機密情報を安全に管理するための一般的な方法です。
# ライセンス
このプロジェクトはMITライセンスの下で公開されています。詳細はLICENSEをご覧ください。
zipコマンドでzipファイルは生成されるが展開できない場合

## 起きたこと
シェル作っている中で、特定のフォルダをzipにする必要があった。
このように、1つ前の階層にある他のフォルダにあるフォルダに対して圧縮しようとした。
```
zip -r ../tmp_oracledb_setup/LINUX.X64_193000_db_home.zip ../tmp_oracledb_setup/LINUX.X64_193000_db_home
```

大きなシェルを作っているので、zip自体は作れているからバグに気づくのに少し時間がかかった。
Oracle関連でいろいろエラーが出ていてなんでだろと思って手動で生成されたファイルを展開しようとしたら、できない。。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179803/c03351f7-2130-9f97-3117-c243b92af419.png)


## 解決方法
調べたら、違うディレクトリのパスを指定してやるとうまくいかなくなることがあるらしい。
cdコマンドで移動してから「../」とかつけずにやったらちゃんと展開できるzipファイルが生成された。
```
now_dir=$(pwd)

cd ../tmp_oracledb_setup/
zip -r LINUX.X64_193000_db_home.zip LINUX.X64_193000_db_home

cd $now_dir
```
[備忘録] IntelliJ(Go)のテスト実行での『No tests were run』問題

# 1. はじめに

しばらくの間、ハマってしまったので、ここにメモとして残します。

最近、Go言語での開発にIntelliJ IDEAを使い始めたのですが、テスト実行で不可解な現象が発生しました。
実行途中でテストが中断され、
**No tests were run** (テストは実施されなかった)
という結果になる現象です。
また、日本語(マルチバイト文字)をログ出力すると、その内容の所々に空白が差し込まれるという問題も起きていました [^1]。

不思議なことにテスト関数名を短くしたり、逆に長くしたりして、良い塩梅の関数名を定義するとテストは動作しました。
しかし、テストのご機嫌をうかがうようなこの対処法では流石に続けられないと、原因を調べることにしました。

![ng-log-mod2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2512108/4c6d5529-7583-7330-26aa-6948a2bfe299.png)


# 2. 環境

Windows 10 Home
IntelliJ IDEA 2023.2.3 (Ultimate Edition)
go 1.19.9


# 3. 原因は？

当初はGo言語のtestingに問題があると思い込んで調査していましたが、特にこれといった有効な情報は見つかりませんでした [^2]。
それもそのはず、原因はIntelliJのコンソールにあったのですから。

IntelliJのコンソールが怪しいと思ったのは、試しにコマンドプロンプトからテストをコマンド実行(`go test`)すると正常動作したためです。
さらにその時は、出力ログに空白が差し込まれることもありませんでした。
これより、IntelliJのコンソール出力処理がログに細工を行うところで問題が起きている可能性が高いと判断しました [^3]。


# 4. 対処法は？

IntelliJ(のコンソール)に余計な仕事をさせないようにすればよいということで、`go.run.processes.with.pty` [^4]をOFFにします。

#### 【設定方法】
1. IntelliJメニューの「Help -> Find Action...」(若しくは`Ctrl+Shift+A`)でアクション一覧を表示し、「Registry」を検索（＆クリック）する。
![idea_registry.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2512108/af0d1add-4f3b-e617-1069-173f1e8bbf58.png)

2. 一覧の「go.run.processes.with.pty」のチェックボックスをOFFにする。
![idea_registry2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2512108/e63c6ecd-432b-b55b-7515-27f4f07a060c.png)


この設定を変更すると、テストが正常に動作するようになりました。
また、出力ログについても、おかしな空白の差し込みはなくなりました。

![ok-log-mod.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2512108/b7676e49-8153-2b2c-8122-fef0379b10fe.png)


# 5. おわりに

問題が解決した後に分かったのですが、[JetBrains YouTrack](https://youtrack.jetbrains.com/issues) を見ると、このような問題がいくつか報告されているようで、その度に「```go.run.processes.with.pty```をOFFにしなさい」というコメントがついていました。
デフォルト設定がOFFにならないものでしょうか:disappointed_relieved:


# 6. 参考にさせていただいた情報

コンソール | GoLand ドキュメント
https://pleiades.io/help/go/settings-console-folding.html


[^1]: 当初はテスト未実施(No tests were run)とは関係ないと思っていましたが、結果的にこれが問題の原因になったのではないかと考えています。

[^2]: 見つけた情報の中には「標準出力に吐き出しているログの末尾に改行がないとテストに失敗する」というものもありましたが、今回の現象はこれには該当しませんでした。

[^3]: たとえば空白を差し込む箇所で特定の1文字を分断してしまい、それがたまたま制御記号になってコンソール処理をクラッシュさせてしまったとか、想像は膨らみますが、このあたりの原因は不明です。

[^4]: このパラメータはコンソール出力の「行の折りたたみ、折り返し、トリミングを制御する」もののようです。
AI-102試験対策のまとめ「Speech Service」

## はじめに
Azure AI Engineer Associate(AI-102)取得に向けた勉強でまとめた内容を本記事では投稿しています。
試験範囲の内容を私が勉強していく中で、
・忘れてしまっていた内容
・他の知識と絡めて理解した方が良い内容
・Microsoft Learnの読解に苦戦した内容
などをできるだけ分かりやすく簡潔にまとめることを意識しています。
Azureの勉強を一から始め、AI-102取得を目指している方の参考になれば幸いです。
※本記事の内容が必ず試験に出るわけではないこと、ご注意ください
※勉強しながら投稿しているため、追加で学んだことがあれば随時投稿内容を更新します。

## 試験対策のまとめ
## Speech Service
音声リソースを使用して音声テキスト変換とテキスト読み上げ機能を提供

### 音声テキスト変換
* リアルタイムまたは非同期でのバッチ文字起こしで音声をテキストに変換
* 下記の様々なソースから音声をテキストに変換
    - マイク
    - オーディオファイル
    - BLOBストレージ
* 話者ダイアライゼーションの技術を使用して、誰が何をいつ言ったのかを判断
* サポートされている言語の一覧と照合して、音声の言語を識別可能
* 下記の場合は基本モデルでは不充分の場合がある
    - 音声に周囲の雑音が含まれている場合
    - 多くの業界/分野の専門用語が含まれている場合

#### **リアルタイムの音声テキスト変換**
* スピーチがマイク/ファイルから認識されると音声が文字起こしされる
* 利用例
    - ライブ会議の文字起こし/キャプション/字幕
    - ダイアライゼーション
    - 発音評価
    - コンタクトセンター エージェントの支援など

#### **バッチ文字起こし**
* ストレージ内の大量のオーディオを文字起こしする場合に使用
* SAS URIでオーディオファイルを示して、非同期に文字起こしの結果を受け取り可能
* 利用例
    - 事前に録音されたオーディオの文字起こし/キャプション/字幕
    - コンタクトセンターの通話後の分析
    - ダイアライゼーションなど

### テキスト読み上げ
* 入力テキストを人間のような合成音声に変換可能
* ディープニューラルネットワークを利用した人間に似た音声であるニューラル音声を使用
    - 事前構築済みのニューラル音声：非常に自然ですぐに使用できる音声
    - カスタムニューラル音声：ユーザーのブランドや製品に固有の音声を作成可能
* 音声合成マークアップ言語(SSML)を使用して下記を調節
    - ピッチ
    - 発音
    - 読み上げ速度
    - ボリュームなど

#### **音声翻訳**
* 音声のリアルタイムの多言語翻訳が可能
* 使用例
    - 音声間翻訳
    - 音声テキスト翻訳

#### **言語識別**
* オーディオで話されている言語を識別
* 使用例
    - 単独での使用
    - 音声テキスト翻訳や音声翻訳と共に使用

#### **話者認識**
* 話者を検証/識別するアルゴリズムを提供
* 使用例
    - 誰が話しているのかを特定する際に使用

#### **発音評価**
* スピーチの発音を評価し、下記に関するフィードバックを話者に提供
    - 音声の正確性
    - 音声の流暢性
* 使用例
    - 言語学習者による発音練習

#### **意図認識**
* 会話言語理解で音声テキスト変換を使用  
    ⇒文字起こしされたユーザーの意図を汲み取る

### コマンド
* WAVとPCM以外の形式を使用する場合  
    ⇒既定のオーディオ形式はWAVのため、フォーマットが必要
    - 例：MP3の場合
        ```C#
        AudioStreamFormat.GetCompressedFormat(AudioStreamContainerFormat.MP3)
        ```
* 音声をテキストに変換する場合  
    ⇒ ```SpeechRecognizer```を使用

#### **圧縮されたオーディオ入力を使用する方法**
```C#
using Microsoft.CognitiveServices.Speech;
using Microsoft.CognitiveServices.Speech.Audio;

// ... omitted for brevity

var speechConfig =
    SpeechConfig.FromSubscription(
        "YourSubscriptionKey",
        "YourServiceRegion");

// Create an audio config specifying the compressed
// audio format and the instance of your input stream class.
var pullStream = AudioInputStream.CreatePullStream(
    AudioStreamFormat.GetCompressedFormat(AudioStreamContainerFormat.MP3));
var audioConfig = AudioConfig.FromStreamInput(pullStream);

using var recognizer = new SpeechRecognizer(speechConfig, audioConfig);
var result = await recognizer.RecognizeOnceAsync();

var text = result.Text;
```

<br>

* 参考
    - https://learn.microsoft.com/ja-jp/azure/ai-services/speech-service/overview
    - https://learn.microsoft.com/ja-jp/azure/ai-services/speech-service/how-to-use-codec-compressed-audio-input-streams?tabs=windows%2Cdebian%2Cjava-android%2Cterminal&pivots=programming-language-csharp

## 次の試験対策のまとめ
* **AI-102試験対策のまとめ「QnA Maker」**

https://qiita.com/fsd-jume/items/aba3911b5eceb98cdd33

## 学習内容をまとめたページの一覧

https://qiita.com/fsd-jume/items/65aba5d5514e023fd66d
[Rider]ブレイクポイント中でもUnityを操作出来るようにしたいとき

# 概要
Riderでブレイクポイントを入れた時、コード上の確認をする分には問題ないですがUnity側は一切操作が出来なくなりInspectorの確認などをしたい時には不便だったりします。そんな時に便利な機能があります。
# 本文
まずは一時停止させたい場所にブレイクポイントを設置（行番号をクリック）します
![スクリーンショット 2023-11-01 8.14.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/6bf58c62-0ba6-ec07-89a9-889a07841be6.png)

次にブレイクポイントを右クリックして「Unity中断ポイントに変換」を押します
![スクリーンショット 2023-11-01 8.14.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/5174e438-326f-d321-a1c7-58ee11e2e7f9.png)

あとはUnityエディターにアタッチ（ウィンドウ右上にある虫のアイコン）を押して
![スクリーンショット 2023-11-01 8.17.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/9663426c-8389-0d77-609e-5be94010f597.png)
Unityを実行すると、設定した地点に来たタイミングに自動で一時停止してくれます。これはUnityの普通の一時停止をしているだけなのでブレイクポイントとは違いUnity上での操作が自由に出来ます。実行を再開したいときはUnityの一時停止ボタンを押すことで続きを始めることもできます。
![スクリーンショット 2023-11-01 8.24.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/9632c43f-c083-8f74-39b5-d45d0c480394.png)


# 補足
「ブレークポイントと例外の表示」を使えば、ここからでもブレイクポイントと一時停止の切り替えをすることができます。設定したポイントを一覧で確認したり、削除したりも出来ますので便利です。
![スクリーンショット 2023-11-01 8.34.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/eeceee1d-06e1-5930-63ec-7f169bcc8dec.png)


# 参考にさせて頂いたリンク
[おすしさんのツイート](https://twitter.com/ssr_maguro/status/1701425396602798306)
コンシューマー鍵とコンシューマーの秘密



+ [rant_type、client_id、client_secretはどこから確認できるのでしょうか？](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007Otjjc)


コンシューマー鍵とコンシューマーの秘密は、クライアント ID とクライアントの秘密とも呼ばれます。詳細は、[「接続アプリケーションおよび OAuth の用語」](https://help.salesforce.com/s/articleView?id=sf.remoteaccess_terminology.htm&language=ja&type=5)を参照してください。

+ [接続アプリケーションのコンシューマー鍵とコンシューマーの秘密の循環](https://help.salesforce.com/s/articleView?id=sf.connected_app_rotate_consumer_details.htm&type=5)

まずは、アプリケーションマネージャーから接続アプリを探して、参照をクリックします。

コンシューマーキーと秘密というところにボタンがあるので、クリックするメールが送信されるので確認コードを入力してください。


コンシューマーキーと秘密が表示されます。
1.) go to Setup > PLATFORM TOOLS > Apps > App Manager
2.) find your connected app
3.) click the little twistie at the end of the line and chose "view"

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/96b8d318-5f67-f928-af95-dc3031c62280.png)

https://developer.salesforce.com/forums/?id=906F0000000AfcgIAC

 

コンシューマーキーと秘密が、それぞれ client_idと client_secretみたいです。
（ややこしい）

 The Consumer Key is the client_id. 

 The Consumer secret is the client_secret. 

https://onlinehelp.coveo.com/en/ces/7.0/administrator/getting_salesforce_client_id_and_client_secret_values.htm
インスタンスリフレッシュ

[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)
[まとめA～M](https://qiita.com/Keiji_otsubo/items/f3ddedee6793bf1576f8)


質問に答えておきながら、自分ではやらかしてしました....

[AP0 インスタンスリフレッシュの影響【2023年11月20】](https://qiita.com/Keiji_otsubo/items/eb9f6b2faaa02c6446b3)


+ [インスタンスリフレッシュの対応について](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007MbFzs)

インスタンスリフレッシュの対応を進めているのですが、以下の２点が気になっています。

・IPアドレス範囲の制限について

　https://help.salesforce.com/s/articleView?id=000384438&type=1

・リードオンリー状態でsalesforceサイトからフォームを実行したらデータはどうなるか



[2020.03.26 「Salesforce - よくあるお問合せを深掘りします：vol.1 - インスタンス移行とセキュリティアラート」 ](https://csminfo.uhuru.jp/hc/ja/articles/900000403343-2020-03-26-Salesforce-%E3%82%88%E3%81%8F%E3%81%82%E3%82%8B%E3%81%8A%E5%95%8F%E5%90%88%E3%81%9B%E3%82%92%E6%B7%B1%E6%8E%98%E3%82%8A%E3%81%97%E3%81%BE%E3%81%99-vol-1-%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E7%A7%BB%E8%A1%8C%E3%81%A8%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E3%82%A2%E3%83%A9%E3%83%BC%E3%83%88-)

# IPアドレス範囲の制限について

 インスタンス移行によって、プライマリのデータセンターが神戸から東京に変更された際に、ホワイトリストに神戸データセンターの IP アドレスしか登録されていない場合、移行後のアクセスに制限が発生することが考えられます。

このようなことが無いよう、Salesforce では「ヘルプに記載の IP アドレスはすべてホワイトリストに登録するように」指示がされています。 

 

# リードオンリー状態でsalesforceサイトからフォームを実行したらデータはどうなるか

単にレコードの保存ができないだけでなく、ファイルのダウンロードやレポートの実行など「システム上に一時データが発生する」作業にも影響が出る点にご注意ください。

併せて、インテグレーション（外部連携）を実装している組織では、送信側組織がリードオンリーモードの場合はバッチが実行されないため「何もなかったこと」になり、受信側組織がリードオンリーモードの場合は、送信側の設定によって再試行が行われます。

Web-to-リードおよびケースについては、リードオンリーモード中は待機キューに保存され、メンテナンス完了後に順次取り込まれるため、特に施策は不要とのことです。

# 関連資料

+ [組織の移行を準備する方法](https://help.salesforce.com/s/articleView?id=000386897&type=1)
+ [Salesforce インスタンスの場所](https://help.salesforce.com/s/articleView?id=000396845&type=1)
+ [製品およびサービスに関するお知らせ](https://help.salesforce.com/s/articleView?id=000387296&type=1)

# 質問

+ [インスタンスリフレッシュに関して](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ak5sKSAQ)
【MongoDB】ソート対象列でnull値があった場合に末尾にしたい


## 概要
例えばPostgreSQLではORDER BY句において、[7.5. 行の並べ替え(ORDER BY)](https://www.postgresql.jp/document/14/html/queries-order.html)のドキュメントにある通り、`NULLS FIRST`や`NULLS LAST`で、ソートにおけるnull値の位置を設定できます。
MongoDBでは2023年11月時点においては、そのような設定は無いようです。では、null値の位置を明示的に設定するにはどうしたらよいか、というのを今回メモ書きします。


## 対応方針
やり方は色々考えられると思いますが、[How to sort null value at the end while in Ascending MongoDB](https://stackoverflow.com/a/69722800)のstackoverflowの回答に書かれている内容が、良いかなと感じました。
対応方針としては、aggregateにおいてソート用のフィールドを設けて、nullの場合は`$ifNull`句で後ろにくるような数値を設定し、その後ソートします。

## 実装サンプル
Goで実装した内容を以下に記します。Go以外でも同様のクエリで期待した結果が得られると思います。

```go
func SampleSortQuery(userAccountId string) ([]modelDb.ResultEntity, error) {
	ctx, _ := context.WithTimeout(context.Background(), 20*time.Second)
	c, err := mongo.Connect(ctx, options.Client().ApplyURI(os.Getenv("DB_CONNECTION")))
	col := c.Database(os.Getenv("DB_NAME")).Collection("sample_collection")
	if col == nil {
		panic(errors.New("can not get collection"))
	}
	var docs []modelDb.ResultEntity

    // ここからクエリの内容
	matchStage := bson.M{"$match": bson.M{
		"user_account_id": userAccountId},
	}
	// display_orderのフィールドで基本ソートするがnullの場合は末尾にする
	addSortStage := bson.M{"$addFields": bson.M{
		"sort_field": bson.M{"$ifNull": bson.A{"$display_order", math.MaxInt32}}},
	}
	sortStage := bson.M{"$sort": bson.M{
		"sort_field": 1},
	}
	projectStage := bson.M{"$project": bson.M{
		"_id":                1,
		"name":               1,
		"description":        1,
	}}

	cur, err := col.Aggregate(context.Background(),
		[]bson.M{
			matchStage, addSortStage, sortStage, projectStage,
		})
	if err != nil {
		return docs, err
	}

	for cur.Next(context.Background()) {
		var doc modelDb.ResultEntity
		if err = cur.Decode(&doc); err != nil {
			return nil, err
		}
		docs = append(docs, doc)
	}
	return docs, nil
}
```
【備忘録】HTML

# HTML（Hyper Text Markup Language）
## 1.htmlとは
文書を構造化し意味付けできるマークアップ言語。
拡張子：**ファイル名.html**
**HTMLレンダリングエンジン**：HTMLを解釈し、それに応じて描画する機能、またはその機能を備えたアプリケーション。
ex) IE, ChromeなどのWebブラウザ
## 2.タグ
###  基本構文
- `html`：文章を全体を囲むタグ
- `head`：文書に関する情報を記述するタグ
- `body`：文書本文を記述するタグ
- `meta`：文書におけるさまざまなメタデータ（文字コードや文書の概要、キーワードなどの文書に関する情報）を表す
- `!DOCTYPE html`：このファイルがHTML5で記述されているという宣言
- `charset=””` 文字コードの宣言
    - `UTF-8`
    - `Shift_JIS`
```
<!DOCTYPE html>
  <head>
  <meta charset="utf-8">
  ここに文書に関する情報を記述
  </head>
  <body>
  ここに本文を記述
  </body>
</html>
```
### h1 ~ h6
見出しタグ
```
<h1></h1>
<h2></h2>
<h3></h3>
<h4></h4>
<h5></h5>
<h6></h6>
```
### br
改行タグ
```
<html>
  <body>
    ここに本文
    <br>
    ここに本文
  </body>
</html>
```
### p
段落タグ
囲われた部分ごとに改行される
```
<p>
  ここに本文
</p>
```
### a
文字がリンクになる
```
<a href=”http://www.yahoo.co.jp/”>この文字がリンクになります。</a>
```
### img
- 画像を挿入する
- src属性のURLの画像が入る
```
<img src=”https://codeprep.jp/api/books/1/cover”>
```
### em
強調タグ
```
<em>この文字が強調される。</em>
<em>マークダウン記法の** 強調 **みたいな感じ</em>
```

### button
ボタン
- `<input type="submit">`との違い
    - 閉じタグがいる
    - form内に置いておくとデフォルトでsubmitが指定されるので何も書かずに済む
```
<button>この文字がボタンになる</button>
```
### 箇条書き
- パンくず：Webサイトのファイル関係の現在の位置を表す
- `ul` 箇条書きを宣言
- `li` 箇条書きで記述
- `ol` 番号書きで記述

```
<ul>
    <li>1箇条</li>
    <li>2箇条</li>
    <li>3箇条</li>
</ul>
<ul>
    <ol>1番</ol>
    <ol>2番</ol>
    <ol>3番</ol>
</ul>
```
### input
- `type` 種類を指定
    - `text`テキストフォーム
        - `size` 横幅を指定
        - `maxlength` 最大入力値を指定
        - `placeholder` 何も入力していないときに透けて見える文字を指定
    - `checkbox` チェックボックス
    - `button` ボタン
    - `radio` ラジオボタン、name要素をそろえることで連携
        - `<label for="">`radioのid名とfor名を同じにすると、ラベルの方をクリックしても選択できる
    - `submit` formで送信
    - その他 https://developer.mozilla.org/ja/docs/Web/HTML/Element/input

### form
`<form method="" action="">`
- `method`
    - `GET` actionに設定したURLに文字をそもまま張り付けて送る、内容が丸見えでセキュリティ面で非推奨
    - `POST` 要素をURLにつけずにかくして遅れるので安全
```
<form method="POST" action="https://hogehoge.com">
    <input type="text" name="hoge" value="">
</form>
```

### select
- プルダウンのセレクトボックス
- selectの方でnameを設定し、optionでvalueを設定することでformで送信できる
```
<select name="name">
    <option value=""></option>
    <option value="1">01</option>
    <option value="2">02</option>
</select>
```

### textarea
- テキストエリア
- `cols` 横に入る文字数
- `rows` 縦に入る文字数 
```
<textarea name="hoge" cols="30" rows="3"></textarea>
```


## 3. ファイル読み込み
### link
- aタグとは役割が大きく違う。
- 外部ファイルやリンクを参照するためのもの。
- 外部の公開ライブラリ(CDN Content Delivery Network) を参照できる。
```
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<a class="btn btn-primary" href="https://getbootstrap.com/docs/3.3/">Bootstrap</a>
<!-- リンクがボタンになる -->
```
### css読み込み
`<link rel="stylesheet" href="">`
- `rel=""`
    - 現在の文書から見たリンク先の関係
    - `stylesheet` スタイルシート(cssですよという宣言)
- `href=""`
    - リンク先の指定
    - `URL` 読み込むスタイルシートファイルを指定
- `media=""`
    - 対象とするメディア
    - `all` すべて
    - `screen` パソコンやスマホ
    - `print` プリンタ
```
<link rel="stylesheet" href=".css/style.css" media="all">
```
### JSファイル読み込み
```
<script src="./js/main.js"></script>
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
```
## 参考
[codeprep](https://codeprep.jp/books/123)
初学者必見：ブランチからプルまでの一般的な開発フロー

# 初学者必見：ブランチからプルまでの一般的な開発フロー

ソフトウェア開発では、複数人での開発を行うにあたり、GitやGitHubを用いた開発フローの理解は必須です。今回は一般的な開発フローについて詳しく説明していきます。

## 1. ブランチを切る

新しい機能の追加やバグ修正を始める際に、まずはブランチを切ります。これは、メインのコードベースに影響を与えずに新しいコードを書くための分離された環境を提供します。

```shell
git checkout -b feature/new-feature
```

## 2. コミットする

ブランチを切ったら、コードの変更をコミットします。コミットは変更セットの単位で、変更内容に対する説明を含めることが良い習慣です。

```shell
git commit -m "Add new feature"
```

## 3. プッシュする

ローカルでのコミットが完了したら、変更をリモートリポジトリにプッシュします。これにより、他の開発者との共同作業が容易になります。

```shell
git push origin feature/new-feature
```

## 4. プルリクエストをする

コードの変更が完了したら、プルリクエスト（Pull Request）を作成します。これは、コードの変更をリポジトリのメインブランチにマージするためのリクエストです。プルリクエストには、変更内容についての説明やテスト結果などを含めることができます。

## 5. 確認修正を行う

他の開発者やレビュワーからフィードバックを受けた場合、プルリクエスト内で修正を行います。レビュワーとの協力を通じて、コードの品質と機能の正確性を確保します。

## 6. LGTMをもらう

LGTM（Looks Good To Me）という承認が得られたら、プルリクエストはリポジトリのメインブランチにマージする準備が整います。この段階で、コードは完成度が高く、品質が担保されているはずです。

## 7. マージする

LGTMをもらったら、プルリクエストをマージします。これにより、変更内容がメインブランチに統合され、新機能や修正が正式にリリースに含まれます。

## 8. プルする

メインブランチに変更がマージされたら、他の開発者もそれを取得する必要があります。これは、リモートリポジトリから最新のコードをローカルにプルすることです。

```shell
git pull origin main
```

以上が、一般的なソフトウェア開発のフローです。効果的なコードの管理とチームでの協力を実現するために、これらのステップを適切に実行することが重要です。開発プロジェクトにおいて、これらの手順はスムーズなコラボレーションと品質の維持に貢献します。
Ruby on RailsのMVCとルーティング

# Ruby on RailsのMVCとルーティング

Ruby on Rails（以下、Rails）は、MVC（Model-View-Controller）アーキテクチャを採用しているフレームワークです。このアーキテクチャは、アプリケーションのコードを整理し、保守性を向上させるのに役立ちます。この記事では、RailsのMVCとルーティングについて詳しく説明します。

## MVCアーキテクチャ

### 1. Model（モデル）
- データとデータベースの操作を担当します。
- ビジネスロジックを定義し、データのバリデーションを管理します。
- ActiveRecordと組み合わせてデータベースと対話します。

### 2. View（ビュー）
- ユーザーに表示される部分を担当します。
- HTMLやテンプレートで表現され、データの表示を制御します。
- ユーザーに情報を提供し、ユーザーインターフェースを構築します。

### 3. Controller（コントローラ）
- ユーザーからのリクエストを受け取り、ModelとViewを制御します。
- ルーティングに基づいて適切なアクションを呼び出し、データの操作やビューの表示を調整します。
- ユーザーとアプリケーションの仲介役です。

MVCの強力な部分は、これらのコンポーネント間の疎結合です。それぞれが異なる責務を持ち、変更が簡単に行えるため、アプリケーションの保守性と拡張性が向上します。

## ルーティング

Railsのルーティングは、URLとコントローラーアクションのマッピングを管理します。これにより、リクエストがどのコントローラーアクションにルーティングされるかが決まります。以下に、Railsのルーティングの要点を示します。

### ルーティングの設定

ルーティングは通常、`config/routes.rb`ファイルで設定されます。例えば、`GET /articles`のリクエストを`articles#index`アクションにルーティングする場合、以下のように記述します：

```ruby
get '/articles', to: 'articles#index'
```

これにより、`/articles`へのGETリクエストが`ArticlesController`の`index`アクションにマッピングされます。

### パスヘルパー

ルーティングはパスヘルパーを提供します。これらのヘルパー関数は、ビュー内で使うことでURLを簡単に生成できます。例えば、`articles_path`を呼び出すと、`/articles`のURLが生成されます。

```ruby
# ビュー内での使用
<%= link_to 'All Articles', articles_path %>
```

### ルート

Railsではルートも定義できます。これは、アプリケーションのトップページを指します。以下は、`root`を設定する例です：

```ruby
root 'welcome#index'
```

この設定により、アプリケーションのトップページが`WelcomeController`の`index`アクションにルーティングされます。

## ルーティングのネスト

Railsではルーティングをネストすることができます。これは、リソース間の親子関係を表現するのに役立ちます。例えば、記事とコメントがあり、記事に対するコメントをネストする場合、次のように設定します：

```ruby
resources :articles do
  resources :comments
end
```

この設定により、`/articles/1/comments/2`のようなURLでコメントにアクセスできます。

## まとめ

Ruby on RailsのMVCアーキテクチャとルーティングは、アプリケーションの設計とURLマッピングを効果的に管理するための強力なツールです。MVCはコードを整理し、ルーティングはリク

エストを適切なコントローラーアクションに導きます。ルート、パスヘルパー、ネストなどの機能を駆使して、柔軟で強力なWebアプリケーションを構築しましょう。