OmniAICreator/Qiita-1.07M huggingface dataset:
オレ的 Win + R(ファイル名を指定して実行)

# はじめに
2025年になって書くはじめての記事は「 **ファイル名を指定して実行** 」です!!
毎回、毎回「まずは○○と入力して、××が開くから～～をクリックして……その次は」
…………とこれが1つなら良い。

しかし、この仕事をしているとそうはいかないのです。
そんなことにリソースを割いているヒマはないのです。

という事で時短テクニックの紹介です。

# 目次

・ **1.ネットワーク**
・ **2.PC構成、設定**
・ **3.周辺機器**


# 1.ネットワーク


`ncpa.cpl`・・・「 **ネットワーク接続** 」を開きます。無線・有線情報を確認できます。<br><br>
`firewall.cpl`・・・「 **Windows Defenderファイアウォール** 」を開きます。
セキュリティ設定で制限されているアプリがないかを確認する際に使用します。<br><br>

`cmd /k ipconfig /all`・・・コマンドプロンプトを開いてIP情報一覧を表示します。
※「cmd」と入力後「Ctrl・Shift + Enter」で管理者起動もできます。<br><br>

`control.exe /name Microsoft.NetworkandSharingCenter`・・・
「 **ネットワークと共有センター** 」を開きます。




# 2.PC構成、設定
`msinfo32`・・・「 **システム情報** 」を開きます。(PC名、型番、CPU情報、メーカー、
メモリ容量、BIOSバージョン)<br><br>
`regedit`・・・「 **レジストリエディター** 」を開きます。PCの根幹を操作します。
結構重要な部分ですね。<br><br>
`systempropertiesperformance.exe`・・・「 **パフォーマンスオプション** 」を開きます。
※PC動作軽減に使用します。<br><br>
`msconfig`・・・「 **システム構成** 」を開きます。セーフモードでの起動、
「 **サービス** 」の起動・無効を編集できます。<br><br>
`control nusrmgr.cpl`・・・「 **ユーザーアカウント** 」を開きます。
資格情報の管理やサインイン中にアカウント情報を確認するのに使用します。<br><br>
`control mmsys.cpl`・・・「 **サウンド** 」を開きます。
マイクの感度や音量を調整、Windows関連のサウンドを変える時にも使用します。<br><br>
`main.cpl`・・・「 **マウスのプロパティ** 」を開きます。マウスカーソル速度、大きさ、
アニメーションを編集するときに使います。<br><br>
`control powercfg.cpl`・・・「 **電源オプション** 」を開きます。
一定時間経過したらスリープ、カバーを閉じたら休止、電源周りの設定編集に使用します。<br><br>
# 3.周辺機器
`appwiz.cpl`・・・「 **プログラムと機能** 」を開きます。アプリのアンインストールに使用します。<br><br>
`mstsc`・・・「 **リモートデスクトップ** 」を開きます。
「 **/v** 」の「***」にPC名やIPアドレスを指定することもできます。

オプションは以下の通りです。
※「 **/f** 」……全画面接続　　「 **/admin** 」……サーバー管理者モード　　
「 **/restrictedadmin** 」……セキュリティ管理者モード<br><br>
`dxdiag`・・・「 **Direct診断ツール** 」が開きます。
PC診断？GPUの情報確認と最近ではあまり使わないですかね。<br><br>
`osk`・・・「 **スクリーンキーボード** 」を表示します。<br><br>
`cmd`・・・「 **コマンドプロンプト** 」を開きます。
※「cmd」と入力後「Ctrl・Shift + Enter」で管理者起動します。<br><br>
`cmd /k ***`・・・「***」に任意のコマンドを書いてEnterで実行も可能です。<br><br>

`cmd /k "CD C:***￥　& ***.exe"`・・・で「**CD**」化とファイル実行を同時にできます。

※ 「****」にはフォルダパスが入ります「**&**」の前後には半角空白1文字をお忘れなく。
<br><br><br>


`powershell -NoExit -Command "Get-PhysicalDisk | Format-Table -Property MediaType,BusType"`<br><br>
PowerShellを開いてストレージ種類(HDDかSSDか)と規格を表示<br><br>

`shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}`・・・
「 **デバイスとプリンター** 」を表示します。Win11でこれを開こうとしてください。
意外とめんどくさい。

えっ!?こっちの桁の方がめんどくさいって？……あっ

<br><br>

 以上です。最後まで閲覧いただきありがとうございました。
Mac端末にWordPressを構築した備忘録

## 1.curlをインストール

brew経由でcurlをインストール
```sh
brew install curl
```

.zshrcに下記を追記
```
export PATH="/usr/local/opt/curl/bin:$PATH"
export LDFLAGS="-L/usr/local/opt/curl/lib"
export CPPFLAGS="-I/usr/local/opt/curl/include"
```
設定を反映
```sh
source ~/.zshrc
```
Homebrewのcurlが使用されているか確認
```sh
which curl
```
出力が/usr/local/opt/curl/bin/curlなどに変わっていれば、Homebrewのcurlが優先される設定になっています。

## 2.phpをインストール
```sh
brew install php
```

## 3. Composerのインストール
```sh
brew install composer
```

## GCCをインストール
```sh
brew install gcc
```

## 4. MySQLのインストール
```sh
brew install mysql
```

## wordpressファイルをダウンロード
ftpソフトでサーバー上のファイルをダウンロード

## データベースファイルをダウンロード
phpmyadminにアクセスし、.sqlファイルをエクスポート

## 新しいデータベースを作成
1.MySQLにログイン
```sh
mysql -u root
```
2.データベースを作成
```sh
CREATE DATABASE wordpress_local;
EXIT;
```

## データベースのインポート
```sh
mysql -u root wordpress_local < /path/to/database_backup.sql
```

## URL情報の更新
1. MySQLにログイン
```sh
mysql -u root wordpress_local
```

2. URLを置換
```sh
UPDATE wp_options SET option_value = 'http://localhost:8080' WHERE option_name = 'siteurl';
UPDATE wp_options SET option_value = 'http://localhost:8080' WHERE option_name = 'home';

UPDATE wp_posts SET guid = REPLACE(guid, 'http://example.com', 'http://localhost:8080');
UPDATE wp_posts SET post_content = REPLACE(post_content, 'http://example.com', 'http://localhost:8080');
```
3. ログアウト
```sh
EXIT
```

## wp-config.phpの設定
WordPressがローカルのデータベースを使用するよう、wp-config.phpを編集します。

wp-config.phpを開く

```sh
nano /path/to/wordpress/wp-config.php
```
データベース接続情報を編集

```sh
define( 'DB_NAME', 'wordpress_local' );   // 作成したローカルデータベース名
define( 'DB_USER', 'root' );             // データベースユーザー
define( 'DB_PASSWORD', '' );             // データベースパスワード（通常空）
define( 'DB_HOST', '127.0.0.1' );        // データベースホスト
```
保存して終了 Ctrl + O → Enter → Ctrl + X。

## 動作確認
PHPのビルトインサーバーで起動
```sh
php -S localhost:8080 -t /path/to/wordpress
```

ブラウザで確認
```arduino
http://localhost:8080
```
Wordpressのアップロードファイルの容量上限が変更できない時の解決方法

### 免責事項
当方、エンジニアリングの基礎的な知識は恥ずかしながら全くないものでして、下記の記載内容については、当方が実際行った作業結果のみを元に記載しているため、正確性や最新性は保証できず、一切の責任を負いかねます。ご利用に際しては、ご自身の判断と責任においてお願いできればと思います。

### 困っていた状況
WordpressのサーバーをLightsailに移行しようとした際のバックアップファイルのアップロード時にファイルの容量上限が80MBになっており、2GBに変更しようとしていたが上手く反映できなかった時のお話です。下記の3つを対応しましたが、全く手応えがなく…と思ったら単純なキャッシュのクリアができていませんでした。

---

#### 1. 設定が正常に反映されているかの確認

```
php -i | grep upload_max_filesize
php -i | grep post_max_size
php -i | grep memory_limit
```
意図した数値になっていればOK。

#### 2. Apache の設定を変更
Apache 側でもアップロードサイズを制限している場合があります。
以下のコマンドで設定ファイルを開きます。
```
sudo nano /opt/bitnami/apache/conf/bitnami/bitnami.conf
```

`<VirtualHost _default_:80>`や`<VirtualHost _default_:443>`の中に、以下を追記します。
```
<Directory "/opt/bitnami/wordpress">
    AllowOverride All
    Require all granted
    LimitRequestBody 2147483648
</Directory>
```

#### 3.wp-config.php の変更
WordPress 自体の設定でも変更を加えます。
```
sudo nano /opt/bitnami/wordpress/wp-config.php
```
ファイルの 最後の方 に以下を追加します。
```
@ini_set( 'upload_max_size' , '2048M' );
@ini_set( 'post_max_size', '2048M');
@ini_set( 'memory_limit', '1024M' );
```
----

### 解決方法
PHP-FPM (FastCGI Process Manager) のキャッシュや設定のリロードが必要だったことを失念していた。

下記コードでapacheだけでなくphp-fpmも再起動したらいけました。
```
sudo /opt/bitnami/ctlscript.sh restart apache
sudo /opt/bitnami/ctlscript.sh restart php-fpm
```

---

### 背景

WordPress (Bitnami) は PHP-FPM を使用 して動作しており、php.ini や wp-config.php の @ ini_set() の変更は、Apache のみの再起動 (restart apache) では反映されない 場合があるとのことです。

✅ PHP-FPM の役割
- PHPの実行を管理 するプロセス (Apacheとは独立)
- php.ini の設定をロードして管理
- upload_max_filesize などの設定変更を適用する

✅ なぜ php-fpm の再起動が必要だったのか
1. php.ini や wp-config.php で upload_max_filesize などを変更
2. PHP-FPM が古い設定をキャッシュしていた (再起動なしでは反映されない)
3. php-fpm を再起動 (restart php-fpm) したことで、新しい設定を読み込んだ
4. WordPress上の最大アップロードサイズが更新された
英語係り受け解析モデルmodernbert-base-english-ud-triangularリリース

[『青空文庫ModernBERTモデルによる国語研長単位係り受け解析』](http://kanji.zinbun.kyoto-u.ac.jp/~yasuoka/publications/2025-02-08.pdf)(情報処理学会研究報告Vol.2025-CH-137『人文科学とコンピュータ』2025年2月8日掲載予定)を横目に、英語係り受け解析モデル「[modernbert-base-english-ud-triangular](https://huggingface.co/KoichiYasuoka/modernbert-base-english-ud-triangular)」を試作してみた。Google Colaboratoryで動かしてみよう。

```
!pip install transformers triton deplacy
from transformers import pipeline
nlp=pipeline("universal-dependencies","KoichiYasuoka/modernbert-base-english-ud-triangular",trust_remote_code=True,aggregation_strategy="simple")
doc=nlp("It don't mean a thing if it ain't got that swing")
import deplacy
deplacy.serve(doc,port=None)
```

「It don't mean a thing if it ain't got that swing」を係り受け解析してみたところ、私(安岡孝一)の手元では、以下の結果が出力された。

```
# text = It don't mean a thing if it ain't got that swing
1	It	_	PRON	_	Case=Nom|Gender=Neut|Number=Sing|Person=3|PronType=Prs	4	nsubj	_	_
2	do	_	AUX	_	Mood=Ind|Number=Plur|Person=3|Tense=Pres|VerbForm=Fin	4	aux	_	SpaceAfter=No
3	n't	_	PART	_	Polarity=Neg	4	advmod	_	_
4	mean	_	VERB	_	VerbForm=Inf	0	root	_	_
5	a	_	DET	_	Definite=Ind|PronType=Art	6	det	_	_
6	thing	_	NOUN	_	Number=Sing	4	obj	_	_
7	if	_	SCONJ	_	_	11	mark	_	_
8	it	_	PRON	_	Case=Nom|Gender=Neut|Number=Sing|Person=3|PronType=Prs	11	nsubj	_	_
9	ai	_	AUX	_	Mood=Ind|Number=Sing|Person=1|Tense=Pres|Typo=Yes|VerbForm=Fin	11	aux	_	SpaceAfter=No
10	n't	_	PART	_	Polarity=Neg	11	advmod	_	_
11	got	_	VERB	_	Tense=Past|VerbForm=Part	4	advcl	_	_
12	that	_	DET	_	Number=Sing|PronType=Dem	13	det	_	_
13	swing	_	NOUN	_	Number=Sing	11	obj	_	SpaceAfter=No
```
![en.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428317/83cf609f-7e46-8a45-f41d-edf8a7673333.png)

トークナイザに手を入れた結果、[昨年12月28日の記事](https://qiita.com/KoichiYasuoka/items/d1fbb04804079a4e495e)に較べて、「don't」や「ain't」が良くなっている。間引きした上三角行列による係り受け解析も、うまく動いているようだ。ただ、さすがに200×200を超える上三角行列は、たとえ間引いても8192トークンに乗らない感じなので、そのあたり、もう少しアイデアが必要かな。
【C#】コード中のコメントに"。"をつけるかつけないか

# はじめに

今回は、コード中のコメントに "。" をつけるかつけないかを考えてみます。

```cs
/// <summary>
/// このメソッドは、何かを行います。
/// </summary>
void DoWork()
{
    // 内容は省略します。
}
```

結論は**どちらでもよいが一貫性をもたせること**です。

## 個人の好みの問題？

JavaScript の ";" よろしく、基本的に句読点はあってもなくてもいいと思います。句読点の歴史的にも読み手が読みやすくするための工夫で必須ではない、とかだったと思います。

つまるところ読みやすさを取るか、僅かなコード量の削減を取るかです。C# ではコメントアウトはコンパイル時に取り除かれるため、出力されるバイナリの大きさに影響しません（メタデータとかも残らない）。ソースコードのみ影響します。

ちなみに、自分は基本的につけません。コメントを区切りたくなったときは改行したりします。

```cs
void DoWork2()
{
    // コメントを区切りたい場合は
    // このように改行します
    // ちなみに // のあとに半角スペースを入れています
    // このほうが視認性がよさそうだからです
}
```

## 一貫性をもたせる

"。" をつけるつけないはリポジトリ作成時に選択し、その後は一貫性をもたせるのがいいと思います。

コンパイル結果に影響しないため混在しても問題はありませんが、コードを読む人の目線だと「なぜ混在しているのか」疑問に感じます。これの確認にリソースを割かないようにするためにも、一貫性をもたせるのがよさそうです。

きっと、足の裏についた米粒のように気になってリファクタしたくなるでしょう。

## おわりに

なぜこんな話をしたかというと、自分もかつてコード中に "。" が混在してリファクタした経緯があったからです。

文字列リテラルにも似たようなことがいえるので、"。" をつけるかつけないかは一貫性をもたせるのがよさそうです。
【Rails】ブランクを禁止しnilは許可するバリデーション

モデルに以下のように記述することで

```rb
validates :some_attribute, presence: true, allow_nil: true
```

- `presence`
指定された属性が空（empty）でないことをチェックする

https://railsguides.jp/active_record_validations.html#presence

- `allow_nil`
対象の値がnilの場合にバリデーションをスキップする

https://railsguides.jp/active_record_validations.html#allow-nil
WSL2(Windows Subsystem Linux 2)の環境構築

## はじめに
WSL2(Windows Subsystem for Linux 2)とは
Windows PC上にて仮想環境としてLinux環境を構築することができる。
AWS環境やLinux環境にSSHする際、便利なのでおすすめです。

(自分のナレッジとしてメモ）


## 注意点
まずはWSL1をインストールし、WSL2へ更新の流れでWSL2とする。


## WSL2のインストール

Windows PowerShellを開いて管理者モードで`wsl --install`でWSLをインストールする。

インストールが完了したら一旦再起動する。

続いてバージョンを確認してみる。
`wsl --list -v`

下記コマンドを実行する。
```
PS C:\> dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

PS C:\> dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

```


PCを再起動する。


Linux カーネルを最新へ更新。
下記URLよりmsiファイルをダウンロードし、適用する。
```
https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi
```


WSL2へ変更。
wslのdefault設定をver 2に変更。


```
PS C:\> wsl --set-default-version 2

WSL 2 との主な違いについては、https://aka.ms/wsl2 を参照してください
```

WSL1からWSL2へ移行。

```
PS C:\> wsl --set-version Ubuntu-18.04 2  

変換中です。この処理には数分かかることがあります...
WSL 2 との主な違いについては、https://aka.ms/wsl2 を参照してください
変換が完了しました。
```

最後に確認してみる。
```
PS C:\> wsl --list -v 
  NAME            STATE           VERSION
  * Ubuntu-18.04    Running         2
```
【PHP7初級】合格体験記

# はじめに
この度、PHP7初級に合格いたしました！
申込手順、勉強方法、知っておくとよい点を残します。
（対象：PHP7初級の受験を悩んでいる方、受験が決まっている方）

# 筆者のスペック
2024年
4月：未経験でIT企業に入社
～6月：Javaの研修を受講
9月：Java Silver11　合格
12月：Python3(基礎試験)　合格

2025年
1月：PHP7初級　合格

PHPは未経験で受験しました。

# 申込方法
①[Odyssey CBT](https://cbt.odyssey-com.co.jp/place/index.html)のサイトから受験会場を探す。
②受験したい教室のサイトに飛び、申し込む。
③受験料を支払う。

※教室によって申込方法や受験料の支払い方法が異なります。フォームに必要事項を入力し、その後、銀行振込か、会場に直接出向いて支払う、といういずれかの形式がメジャーだと感じます。

# 勉強期間
1週間ほど

# 勉強方法
今回受験するにあたり、

- 黒本([徹底攻略PHP7技術者認定［初級］試験問題集](https://book.impress.co.jp/books/1118101075))
- 無料の模擬試験サイト([PRIME STUDY](https://study.prime-strategy.co.jp/))

を用いて学習しました。

順序は、
- 黒本1周目（5日）
- 黒本2周目（3日：最後の1日は試験当日の朝）
- PRIME STUDY（試験当日の朝）
- 黒本の間違えた問題のみを1周（試験当日の朝）

という流れで勉強しました（ぎりぎりにならないと動けないタイプです^^;）。

# 知っておくとよい点
※試験内容が全く同じになることはあまりないかと思いますので、あくまでも参考程度になさってください。

・基礎試験だからか、複雑なソースを読む問題はほとんどなかった。
・それよりも、一つ一つの知識を問われていた傾向。PHP特有のものであったり、知らない用語が出てきたらだいたいでいいので意味を把握しておくと点数に繋がるかもしれない。
・DB系の問題は、黒本でも出題されているが、基礎の基礎を問われる可能性があり、得点源になるので確実に抑えておく。
・難易度的に、黒本=試験<PRIME STUDYの模擬試験と、PRIME STUDYは少し難易度が高めだが、知識の整理に役立つので、時間がなくてもさらっとだけでも見ておくと良い(役に立った点：問題の選択肢に書いてあることが細かい点。正しい選択肢がそのまま、用語や概念の解説のようになっている)。

# さいごに
今携わっている案件で使用されており、知識をつけたく、今回受験を決めました。
体系的に勉強を進めることができ、PHPがどんな言語なのかを知るのにすごくいいと感じました。受験を悩まれている方は、ぜひ受験してみられるといいかと思います！
黒本が出版されたらPHP8も受験してみたいと思いました。
この記事が参考になったと感じていただけましたら幸いです。
kintone JavaScriptカスタマイズでのレコード上のデータを参照する際の文字列の正しい扱い方（ドット記法・ブラケット記法）

## 1. はじめに

[前回の記事](https\://qiita.com/\_muraham/items/38279f7499f12a761aff) で、REST API利用時のクエリ記法について触れましたが、文字列操作の説明の続きとして、今回は「レコードにアクセスするときのブラケット記法とドット記法」について、詳しく掘り下げていきたいと思います。

kintoneアプリ開発では、レコードデータにアクセスすることが多いですが、JSの記法に慣れてないと混乱しがちです。それぞれの記法がどのように機能するのか、そしてどちらを使うべきなのか、具体例を交えながら説明していきます。
混乱したり迷った際はこの記事を見返してもらえるとうれしいです。

## 2. 基本のデータ構造とアクセス方法

kintoneでは、レコードの各フィールドはオブジェクト形式で保持されています。このオブジェクトには、フィールドコードをキーとしてアクセスします。

例として、以下のようなレコードデータを考えてみましょう：

```javascript
const record = {
    customerName: {
        value: "山田 太郎"
    },
    orderNumber: {
        value: "12345"
    }
};
```

このデータにアクセスする際、主に2つの記法があります。

- **ドット記法**
- **ブラケット記法**

## 3. ドット記法

ドット記法は、フィールドコードを直接指定してアクセスする方法です。

```javascript
console.log(record.customerName.value); // "山田 太郎"
```

また、キー名が日本語（つまり、フィールドコードが日本語）でも問題なくアクセスできます。
```javascript
console.log(record.名前.value); // フィールドコードが「名前」の場合
```

### メリット

- コードが簡潔で読みやすい。
- タイプ数が少なく済む。
- エディタの補完機能を活用しやすい。

### デメリット

- フィールドコードが固定で、動的に指定したい場合には使えない。



## 4. ブラケット記法

ブラケット記法では、キーを文字列で指定します。この方法は、フィールドコードを変数として扱う場合に便利です。

```javascript
console.log(record["customerName"].value); // "山田 太郎"
````````````

下記のように変数を利用することができるのがブラケット記法の強みです。
（故に、動的にフィールドコードを指定できます！）
```javascript
const fieldCode = "customerName";
console.log(record[fieldCode].value); // "山田 太郎"
```

※JSの記法上、ダブルクォーテーションで囲まれていると文字列、囲まれていない場合は変数になるので初学者の場合はここが混乱ポイントですね。
上記２つの例を見比べると理解できると思いますので困ったら見返してみてください。

### メリット

- フィールドコードを動的に指定できる。
- 特定の文字（例: ハイフンやスペース）が含まれるキーにも対応可能。

### デメリット

- ドット記法に比べて少し長くなるので、タイプ数が増える。
- エディタの補完機能を活用しにくい。

## 5. どちらを使うべき？

- **固定的なフィールドコードを使用する場合**: ドット記法を使うことで、コードの可読性を保てます。
- **動的にフィールドコードを扱う場合**: ブラケット記法を使用する必要があります。

例えば、動的にフィールドコードを生成するケースでは、ブラケット記法が必須となります。

```javascript
const fieldCodes = ["customerName", "orderNumber"];
fieldCodes.forEach((code) => {
    console.log(record[code].value);
});
```

## 6. まとめ

ドット記法とブラケット記法、それぞれにメリットとデメリットがあり、使い分けが重要です。
個人的には、基本的にはドット記法が楽なのでドット記法を使い、必要になったらブラケット記法を使うようにしています。
一方で常にブラケット記法で書かれるのを好む方もいますので、プロジェクトや関わるメンバー同士で決めてもらえればいいと思います！
優先順位付きキューを理解してみた

## はじめに
新年の目標として毎日leetcodeのdaily challengeを解くようにしていますが、今日の問題は以下のものでした。

![Screenshot 2025-01-19 at 22.44.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3754242/ab637e2c-7598-9757-25ad-83be2b0e7e94.png)

https://leetcode.com/problems/trapping-rain-water-ii/description/

🤔🤔🤔🤔🤔

水たまりにどれだけ水が溜まっているかを計算するということだけはわかりました。

まず1時間をかけて格闘してみたのですが、解けず...

諦めてsolutionを見ると`Min heap(最小ヒープ)`、`優先順位キュー`、`完全２分木`などのワードが出てきていました。バイナリーツリーについて概念は知っているけど...

ということで今回は優先順位付きキューについて理解してみました！

## Heap（ヒープ）とは？
Web開発をしているとブラウザのヒープメモリを使う、みたいな言葉はよく聞いていたのですが、そもそもヒープとはなんでしょう？

### 定義

英語での言葉の意味だけで見ると、「集合体」のような意味合いを持ちます。

そして、コンピューターサイエンス的には以下のような意味です。

>  ヒープ（heap）とは、データ構造の一種で、木構造(ツリー構造)のうち、親要素が子要素より常に大きい(あるいは小さい)という条件を満たすもの。また、コンピュータプログラムが利用するメモリ領域の種類の一つで、実行時に任意のタイミングで確保や解放が可能なものをヒープ領域というが、これをヒープと略す場合がある。

https://e-words.jp/w/%E3%83%92%E3%83%BC%E3%83%97.html

### 優先度がつけられている
要するに、ヒープは優先順位がある大きな箱です。

救急病院だと、患者が来た時緊急度をもとに診療を行う必要があります。
先着順ではなく緊急度を考える必要がありますよね。

このような時にヒープを使うことができます。

### 種類
このヒープは大きな数字から並べると`Max Heap`（最大ヒープ）、小さい数字から並べると`Min Heap`で分けられます。

以下図のようなイメージです。

![Screenshot 2025-01-19 at 22.58.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3754242/628fc643-44bd-9109-5820-f237c03d5072.png)

### 特性
1. 親は子より小さい（Min Heap)か大きい（Max Heap）
2. 必ず左から埋める必要がある（空きを許さない）

このような特性を持つ構造を`完全２分木`と呼びます。

上の図を見るとわかるように、２分探索木と違って重複があってもいいです。

### 概念の整理
ヒープ、優先順位付き、完全２分木という言葉が出てきて少しわかりにくくなりましたね。
ここで一旦概念を整理したいと思います。

#### 完全二分木

以下のような形だけを表す概念です

- 最下層を除いて、全ての層がノードで埋まっている
- 最下層は左から順に詰めて配置される

これは「構造」を説明する用語です。

#### ヒープ

完全二分木の形を持ちながら、親子間の大小関係が決まっているデータ構造

データ構造のことです。

#### 優先度付きキュー

優先度の高い要素から順に取り出せるもの全てを指す言葉です。
その実装方法の1つとしてヒープがよく使われるって感じです。

抽象的な「データの型」を意味します。

## Insert
ヒープを使うと何が嬉しいかを知るために、ヒープの挿入演算について考えていきたいと思います。

引き続き救急病院のケースで、以下のようなヒープを考えてみましょう。
勝手に症状に優先度をつけてみています。

```
　1(心臓麻痺)
   /   \
3(骨折) 4(風邪)
```

ここで、2(急性アレルギー反応)という新しい患者が入ってきたとします。
そうすると以下のようなロジックで患者を処理して行きます。

1. とりあえずヒープの最後に入れる

```
　　　1
   /   \
  4     3
 /
2
```

2. 親と比較する
2は4より小さい？　→ 「はい」であるため2と4の位置を交換します。

```
     1
   /   \
  2     3
 /
4
```

3. 続けて親と比較
2は1より小さい？　→ 「いいえ」であるため、処理を止める

そうやって新しい値は

1. 最も深い層の左に詰めて入れて
2. 親より小さかったら上に登って
3. 親より大きかったら止まる

処理を続けることによって正しい優先順位の位置を探して入ります。

## おわりに
やはりデータ構造やアルゴリズム自体を知らないとどう頑張っても解けない問題がありますよね...

思考の範囲を広げるためにももっと勉強していきたいですね！

## 出典

https://velog.io/@yun8565/%EC%9A%B0%EC%84%A0%EC%88%9C%EC%9C%84-%ED%81%90-Priority-Queue

https://lipcoder.tistory.com/100
MidJourney Promptを活用する最高の法方

最近、AIアートが解禁され、自分だけの美しいイラストを生成できる「MidJourney」が大事な話題となっています。しかし、素晴らしい作品を生み出すためには、有効なプロンプトを書くことが重要です。この文章では、キーワード『MidJourney Prompt』に関する情報と、プロンプトを最大限に活用する方法をご紹介します。

MidJourney Promptとは何か？

MidJourney Promptとは、AIがイラストを生成するために用いる指示文です。いかに簡単な言葉でも、それを立体的にして書くことで、想像以上に高質なアートワークを生み出せます。たとえば、「花」という一言よりも、「三月の春の花園」や「蓮が潜む青い水面」と書いた方が、よりリアルな作品を生むことができます。

推奨のツール、https://midjourneysref.com/ja

MidJourney Promptを使いこなすためには、https://midjourneysref.com/ja が活躍します。このサイトでは、各種のスタイルを紹介し、いかに自分の想像するイラストを生成するかを学べます。プロンプトの例の付け方や、有用なキーワードの集め方などが提供されています。

例:

たとえば「黒と金のカラースキームストーリーアート」というプロンプトでは、金色の絶景と神秘的なスタイルを持つイラストを生成できます。これらの積み重ねが、個性的で高質な作品を作り出すためのキーです。

MidJourney Promptを構築するテクニック

詳しい言語を使う

個別の情報を追加しましょう。たとえば、「江戸風描画」や「新世代アバンギャルドアート」など。

カラーを指定する

純粋な白黒や、いくつかの色の組み合わせを書くだけで、魅力的な色合わせを生成できます。

画面の構成を記載

アングルやパースペクティブの素材を明確にしましょう。

MidJourney Promptを駆使して、自分だけの素晴らしいアートワークを作りませんか？他にないアイデアを実現できるはずです。一度試してみて下さい！
LINE: 公式アカウント入門


 LINE 公式アカウントに関係する基本的な情報をまとめました。

* [公式アカウントを作成してみる(2025/1/19)](https://qiita.com/frozencatpisces/items/54cbc141478935696db1)

* [Messaging APIを用いてWindowsのcurlコマンドからメッセージを投稿する(2025/2/16)](https://qiita.com/frozencatpisces/items/28cfa36c04a389128363)

* [プロフィール画面を設定する(2025/4/20)](https://qiita.com/frozencatpisces/items/c0709564037b740a2335)

* [トーク画面にリッチメニューを表示する(2025/5/18)](https://qiita.com/frozencatpisces/items/7b29fd994cb604d4c729)

* [クーポンを作成する(2025/6/15)](https://qiita.com/frozencatpisces/items/e0cd549ac11d69f253b6)
S3のライフサイクルルールを設定してS3バケット内のファイルを移動してみた

## 概要
S3のライフサイクルルールを使用してバケット内にあるファイルを
一定期間経過後に移行するように設定していきます。

## S3ライフサイクルルールとは
S3に保存されているファイルを違うストレージクラスに移動したり、
設定した期間で削除したりするときに使用する設定になります。

参考：https://dev.classmethod.jp/articles/3minutes-s3-versioning-lifecycle/

## 実施手順
今回は簡単にバケット内にあるファイルを1日後に別のストレージクラスへ
移行する設定を実施していきます。

（１）S3に新しくバケットを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3975072/0528aaf1-f27a-de35-debc-e225cdd66997.png)

（２）S3バケットの管理タブより「ライフサイクルルールを作成する」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3975072/77777570-8655-d912-cfbc-6507a4d5fea9.png)

（３）ライフサイクルルール名は任意の名前に設定し、今回はバケット内の
　　　すべてのオブジェクトにルールを適用。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3975072/44cc46ba-cf93-b493-658d-0bf87c2731b6.png)

（４）今回は一番単純な「現行バージョンのオブジェクトをストレージクラス間で移行する」に設定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3975072/f80fc61a-739a-7fb7-fe05-be5351d52386.png)

（５）S3バケット内にアップロードされたファイルを1日後にGlacier Flexible Retrievalへアップロードするように設定。これでルールの作成を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3975072/5832b481-a847-f50a-5b82-6439820ce8eb.png)

（6）ルールの作成完了後に管理タブ内に作成したルールが表示されたことを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3975072/0be117fc-030e-7b61-ff40-2a9de5efe1a0.png)

（7）S3にファイルをバケット内へアップロード。
これで1日後に移行されていれば、設定が正しくされていることになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3975072/e836ca2f-c7ec-564e-824b-f45d94312d89.png)

1日経過後には以下の通り、ストレージクラスが変更されておりルール通り
移行が正しく実施されていることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3975072/7e373f65-4ada-2980-528d-53ff4557657c.png)

なおデフォルトでは128kb未満のファイルにはルールは適用されないので注意が必要です。

## まとめ
今回は簡単にですが、ライフサイクルルールでファイルの移行を実施してみました。
実務でもバケット内の整理でライフサイクルルールを使用することもあると思うので
もう少し複雑な設定も今後取り組んでいけたらなと思います。
初心者がJavaで初めての「成果物」

# Javaでソート修行してみた

Javaでの初ビッグプロジェクトはバブルソートを完成させることだった。forループを二重に使う邪道な手法は避け、Whileとforを組み合わせて完成させた超大作だ。初心者ならソートをやれば力はつくと思うが、写経はやめて自分で考えたやり方でプログラムを作るべきだ。自分の頭でソートが完成できたら、その先なんでも応用が利き、難しい壁にぶち当たっても乗り越えられる素養が得られるはずだ。


 ```java:Bubble Sort in Java
   public void bubbleSort(){

        int[] numbers = {4,7,2,9,33,6,5,8,3,43,1,88,0,21};
        int iLen = numbers.length;
        int iLarge = 0;
        int totalComparison = 0;
        int iLen1 = 0;

        System.out.print("Before sort : ");

        for(int y = 0; y< iLen; y++){

            System.out.printf("%d,", numbers[y]);
    
         }
         System.out.printf("\n");
        
        while(iLen1 < iLen){

             for(int i = 0 ; i < iLen - 1 - iLen1; i ++){

                 if(numbers[i] > numbers[i + 1]){

                iLarge = numbers[i];
                numbers[i] = numbers[i + 1];
                numbers[i + 1] = iLarge;

                totalComparison++;

            }

        }

        iLen1++;

        }

        System.out.printf("Total comparizon : %d \nAfter sort : ", totalComparison);
        for(int y = 0; y< iLen; y++){

        System.out.printf("%d,", numbers[y]);

     }

    }
ServiceNow フィルターナビゲーターからのリストビュー表示を別タブで表示する

## 結論
フィルターナビゲーターからのリストビュー表示を別タブで表示する方法の紹介です。
超小ネタなので背景とかなしに結論だけ先に書きます。
[テーブル名].listで表示させていた　**「list」を大文字の「LIST」に変更してください。**
これだけです。
フィルターナビゲーターに[テーブル名].listで該当のテーブルのリスト表示ができることは結構知られていると思いますが、
もともと開いていた画面は残しつつ、別タブで分けて情報を見たい！などの時に使えると思います。

## 実演

### 小文字「list」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3989988/92116fd1-65f2-828a-0740-3bb2dac45932.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3989988/17079dc7-33f6-ebf2-0161-30e1c0a78db2.png)


### 大文字「LIST」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3989988/f178b49c-7b72-4ee4-3142-b7adc67897ed.png)

別タブで開きました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3989988/e7629456-e659-9377-238d-4789c85128c0.png)



## まとめ
・もともとアプリケーションメニューにあるものを別タブで開くだけであれば、「Ctrlキー＋リンクをクリック」（ブラウザ自体の別タブで開く機能ですね）で別タブでそのままフィルタ条件なども維持して別タブで開きます。
・アプリケーションメニューにないテーブルなど、調査や開発時に別タブで情報見れるように出しておきたい、時にLISTを大文字で打ち込めば別タブで開けますで、頭の片隅に置いておくと役立つ時が来るかも？


以上
Microsoft Power Automate Desktop の Automate Web Browser でのバグ

Microsoft Power Automate Desktop
バージョン: 2.51.00234.24355
Micorosoft Storeのバージョン: 11.2412.244.0
更新後にAutomate Web Browserでバグが発生するようになってしまいました。

リンクをクリックする度に、以下の「警告」が表示され許可を求めてきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642921/d8a4e4ef-55e1-267a-66d3-3c7cb83dceb2.png)

A website is atteptiong to open an external application on your computer.Are you sure you want to proceed?
ウェブサイトがコンピュータ上で外部アプリケーションを開こうとしています。続行してもよろしいですか?

Automate Web BrowserはInternet Explorer互換のWebブラウザで古いシステムをPADで利用するには必須です。

現在のところ対応策はありません。
ストア版のためダウングレードもできないし、まいりました…。

Microsoftのコミュニティでも解決されていないようです。
https://community.powerplatform.com/forums/thread/details/?threadid=c1027258-e7d1-ef11-8eea-7c1e5218489c

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642921/593a5369-9a68-f1a8-01f1-affc9f808b53.png)
TryHackMeでサイバーセキュリティを学ぶ①

サイバーセキュリティを勉強するため、実践的なトレーニングができるらしいTryHackMeを利用し始めた。
https://tryhackme.com/

最初にアカウント登録をすると、”SOC Level 1”の学習を勧められた。
まずは勧めに従い学習を開始した。
![SOC_Level_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733524/cd4a35bd-3325-4022-0863-70ad41f79590.jpeg)

”SOC Level 1”メニューの中でも、まずは"Junior Security Analyst Intro"という項目を学習することにした。

ここでは、ひよっこセキュリティアナリストとしてトリアージ（セキュリティ対策の優先順位決め）などをするらしい。

ガイダンスに従って、簡単なアクセスログ確認・脅威のエスカレーションなどを行い、
アナリストの作業を疑似体験できた。
無料で利用できる（一部有料）が、個人的には、教材は分かりやすく作成されているし、手を動かす機会が多く理解を深めやすいと感じた。

今後少しずつ他項目も学習していきたい。
そして、仮想マシンを使ったハッキング体験もできるそうなので、その辺りも勉強してみたいと考えている。
![list.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733524/0a9858c9-0f70-cc7a-2d83-378126afe3ce.jpeg)
Pythonを使うときはvenvを使え高校校歌

# venvを使うことになった背景
学校でpythonを使うことが多くライブラリーを入れることが多い。ふと思ったのだ、あれ環境が汚れて行ってるくねと、
# venvの使い方
WindowsとMac/linuxとでは挙動が異なる。それを深く解説していく。
```bash:MacOS/Linux
python3 -m venv 任意のフォルダー名
```
```powershell:Windows
python -m venv 任意のフォルダー名
```
構文はこうだが、たいてい下のように暗黙のルール？？的なのが存在している。.venvにしてることが多い(わかりやすいため)
```bash:MacOS/Linux
python3 -m venv .venv
```
```powershell:Windows
python -m venv .venv
```
そしてここからが大事だ。venvの環境に入るときMac/linuxとWindowsで打ち込むコードが違う。
```bash:MacOS/Linux
source ./作ったフォルダ名/bin/activate
```
```powershell:Windows
.\作ったフォルダ名\Scripts\activate
```
暗黙のルールに従った書き方だと
```bash:MacOS/Linux
source ./.venv/bin/activate
```
```powershell:Windows
.\.venv\Scripts\activate
```
:::note warn
Windowsの方へ
おそらくこれを実行してもこんな感じに怒られるはずです。これはスクリプトの実行が無効になっているので使えるようにしときましょう。
```powershell
.\.venv\Scripts\activate : このシステムではスクリプトの実行が無効になっているため、ファイル C:\Users\XXX\.venv\Script
s\Activate.ps1 を読み込むことができません。詳細については、「about_Execution_Policies」(https://go.microsoft.com/fwlink
/?LinkID=135170) を参照してください。
発生場所 行:1 文字:1
+ .\.venv\Scripts\activate
+ ~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : セキュリティ エラー: (: ) []、PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess
```
```powershell:１度だけ(管理者不要)←おすすめ！！！
Set-ExecutionPolicy RemoteSigned -Scope Process
```
```powershell:常時有効※セキュリティ的におすすめしません(管理者必要)
Set-ExecutionPolicy RemoteSigned
```
:::
すると、こんな感じになり、venvが使えるようになります！！！

```bash
(.venv) user@XXXX:~$
```
```powershell:Windows
(.venv) PS C:\Users\XXXX>
```
このまま実行したりpipを使うと自動的にvenv内で動きます
# venvを抜けたいとき
MacOS/LinuxとWindows共通のコマンドで抜けられます
```bash:Windows+MacOS/Linux
deactivate
```

# 最後に
今回、学校で開発をするときに、環境が汚れるの嫌だったのでvenvを紹介しました。
では、よき開発ライフを！
大学入学共通テスト2025から初教科の情報のプログラミング分野のコードを実際に書いてみた（リファクタリング付き）

# 筆者について

```
name → Koki Teramoto
age → 18
language → ja_JP, en_US
```

# 本編

今日は大学共通テスト２日目でした！リアルタイムに解いてた受験生としてはどんな問題が出るのがオドオドしていたのですが、実際は模試に出たコードなんかよりもよっぽど簡単なものでした。今回は、実際に出た問題をPythonでコード化して、リファクタリングしていきたいと思います。

https://x.com/_0_terarin_0_/status/1880952473105686800

## 問題について

さて、問題は新聞やもう少しすると過去問として大学入試センターに載ったりしますので、各自こちらの方は見ていただきたいと思います。参考までに、福祉新聞が問題をPDFで掲載していますのでそちらのリンクを載せておきます。

https://www.fukuishimbun.co.jp/articles/-/2217520

プログラミング分野の問題は第３問で出題されました。要するに、以下のような問題です。

- あなたは今工芸部にいる！
- あなた含めて３人の部員と共に９つの作品を作る。
- 作品ごとにかかる作成日数がある。
- 作品は１番のものから順番に作っていき、一番最初に手持ち無沙汰になる人が次作品を担当する

まあこんな感じです。詳しくは問題を読んでください。

## 最終的に問題で出るコード

最終的に問題を解いて行ったら以下のようなコードに辿り着きます（というかたどり着いて欲しい）

```python:original.py
Nissu = [4,1,3,1,3,4,2,4,3]
kougeihinsu = 9
Akibi = [1,1,1]
buinsu = 3
for koigeihin in range(0,kougeihinsu):
    tantou = 1
    for buin in range(1, buinsu):
        if Akibi[buin] < Akibi[tantou - 1]:
            tantou = buin + 1
    print(f'工芸品{koigeihin + 1}→部員{tantou}:{Akibi[tantou - 1]}日目〜{Akibi[tantou - 1] + Nissu[koigeihin] - 1}日目')
    Akibi[tantou - 1] = Akibi[tantou - 1] + Nissu[koigeihin]
```

なんて見にくいことでしょうか。ちょっとオリジナルから変えてるとこもあるのですが、おおかた元通りのプログラムです。このコードには上方以外の人からでもツッコミが多発してしまいそうです。

- 無駄な変数が多い
- なんで配列のインデックスやのに0基準じゃなくて1基準やねん
- まずそも変数の名前ローマ字やめぃ
- for文多すぎる問題

なんかそんな大したことないプログラムなのにいかにもすごいプログラムかのように見えます。ということで、上で列挙した点を改善したプログラムを作成しました。

```python:improved.py
days_to_make = [4,1,3,1,3,4,2,4,3]
num_works = 9
days_clear = [1,1,1]
num_members = 3
for index_works in range(num_works):
    min_index = days_clear.index(min(days_clear))
    print(f'工芸品{index_works + 1}→部員{min_index + 1}:{days_clear[min_index]}日目〜{days_clear[min_index] + days_to_make[index_works] - 1}日目')
    days_clear[min_index] = days_clear[min_index] + days_to_make[index_works]
```

これでどうでしょうか！すっかり見やすくなったと思います。ちなみに、元ツイでも書いているのですが、これ多分ロジックを考えさせるためにMax関数を使わないようにしてる気がするんですよね。それなら元のコードの`for`のネストも納得ですが、まあそれならそれで`if-else`を使った方がより直感的に見やすいとは思いますね。

# 最後に

今回の共通テスト、なんか今年は国語でヒス構文おばさんとか色々出てて面白かったですね。来年以降も情報分野に関しては成り行きを追っていきたいと思います。ちなみに、今回はGitHubに一応ソースコードも公開してますので是非ご利用くださいませ（大学入試センターの人に届け！）

https://github.com/0-terarin-0/prv_python_theCommonTestForUniversityAdmissions2025

僕は共通テスト受けて（しかも社会２科目理科２科目の１０科目フル受験）疲れたので就寝したいと思います。おやすみなさい〜
cowsayをランダム（シャッフル）でキャラを表示

**cowsayを知ったのは、2025年1月1日のポストがきっかけでした。**


![x_cowsay1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666798/098aa88d-e6ac-b53e-9d4f-5bb4aac85b89.png)

**cowsayは、入力した文章をアスキーアートのキャラに吹き出してもらうだけのアプリで、オプション"-f"でキャラ名を指定すると、出したいキャラが出てきます。lolcatでもっと楽しくなります。**

**なので、
実行毎にキャラをランダムで出せないかなと思い、シェルスクリプトを作ってみました。（ほとんど作ってませんが）**

**$randomの使い方がよくわからず、もっと簡単にできないかなと思い、randomを検索すると一緒にでてくる、shufコマンドを使うことにしました。**


+ #### まずは、cowsayとlolcatをインストール

```bash
sudo apt install cowsay && apt install lolcat
```


+ #### 完成したシェルスクリプト

```bash
#!/bin/bash

cow=$(cowsay -l | tail -n +2 | tr -s '[:space:]' '\n' | shuf -n 1 )
# "$(cowsay -l | tail -n +2 | tr -s '[:space:]' '\n'"は、下記のサイトから入手
cowsay -f $cow "$cow" | lolcat -a
```

+ #### とりあえず処理を追ってみます。

#### 1\. キャラリストを取得
```bash
cowsay -l
```
#### 実行結果
```
Cow files in /usr/share/cowsay/cows: １行目
apt bud-frogs bunny calvin cheese cock cower daemon default dragon
dragon-and-cow duck elephant elephant-in-snake eyes flaming-sheep fox
ghostbusters gnu hellokitty kangaroo kiss koala kosh luke-koala
mech-and-cow milk moofasa moose pony pony-smaller ren sheep skeleton
snowman stegosaurus stimpy suse three-eyes turkey turtle tux unipony
unipony-smaller vader vader-koala www
```

#### 2\. 1行目を削除
```bash
tail -n +2　
#(-1+2)で1行目らしい
```
https://manpages.ubuntu.com/manpages/noble/en/man1/tail.1.html

#### 実行結果
```
apt bud-frogs bunny calvin cheese cock cower daemon default dragon
dragon-and-cow duck elephant elephant-in-snake eyes flaming-sheep fox
ghostbusters gnu hellokitty kangaroo kiss koala kosh luke-koala
mech-and-cow milk moofasa moose pony pony-smaller ren sheep skeleton
snowman stegosaurus stimpy suse three-eyes turkey turtle tux unipony
unipony-smaller vader vader-koala www
```

#### 3\.スペースを指定して、改行する
```bash
tr -s '[:space:]' '\n'
```
https://manpages.ubuntu.com/manpages/noble/en/man1/tr.1plan9.html

#### 実行結果
```
apt
bud-frogs
bunny
calvin
cheese
cock
cower
daemon
etc..
```
#### 4\. 改行したリストをシャッフルして、1行目を取得
```bash
shuf -n 1
```
https://manpages.ubuntu.com/manpages/noble/en/man1/shuf.1.html
#### 5\. cowsayにキャラ名を渡して、lolcatで色付けする
```bash
cowsay -f $cow "$cow" | lolcat -a
```
#### 実行結果

![cowsay1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666798/c0cfd00e-b8f6-cc63-c7f0-1f37550f67d0.png)
![cowsay2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666798/23320ac5-4327-94bf-923f-22b7e351a30e.png)



#### 参考にしたサイト

https://qiita.com/OtsukaTomoaki/items/296835c2cfe9dba2d2fb

https://orebibou.com/ja/home/201606/20160611_001/
【リーダブルコード】初心者エンジニアが読み解く「読みやすいコード」の書き方 - 第1章

はじめまして。
2025年1月より未経験からITエンジニアとして働き始めた、マル太です。

<br>未経験からのスタートなので、毎日が勉強です。

<br>現在、エンジニアの必読書と言われる「リーダブルコード」を読んでいます。
この本は、「読みやすいコード」の書き方を教えてくれる本です。

<br>正直なところ、作中のコードの内容については十分理解できていませんが。。。

まずは一通り本書を読んでみようと思い、本書を読み進める中で、
「初心者の私にも役立つ情報がたくさんある」と感じたので、Qiitaにまとめてみることにしました。

同じように未経験からエンジニアになった方の参考になれば幸いです。


<br>今回は、第1章「理解しやすいコード」の内容を、私なりにまとめてみます。


<br><br>
## 読みやすいコードを書くことはなぜ重要なのか
<br>1章では、「コードは読みやすく書くべきである」と述べられています。

なぜなら、プログラミングでは、コードを読む時間の方が、書く時間よりもずっと多いからです。

他の人が書いたコードを読むのはもちろん、自分が過去に書いたコードを読み返すことも頻繁にあります。

もしコードが読みにくかったら、どうなるでしょうか？

・理解するのに時間がかかってしまいます。
・バグを見つけるのが難しくなってしまいます。
<br>


## 読みやすいコードを書くためのポイント
<br>1章では、読みやすいコードを書くためのポイントとして、以下の点が挙げられています。

<br>**・変数や関数には分かりやすい名前をつける**
変数や関数に名前をつけるときは、`a`や`b`のような、意味のわからない名前は避けましょう。
`user_name`や`total_price`のように、どんな値が入っているのか、ひと目でわかる名前をつけましょう。
<br>

※変数って？
変数とは、値を格納するための箱のようなものです。
例えば、`user_name`という変数には、「山田太郎」さんのようなユーザーの名前を格納することができます。
変数名は、その箱に何が入っているのかを表すラベルのような役割を果たします。

※関数って？
関数は、特定の処理をまとめて名前を付けたものです。
例えば、商品の合計金額を計算する処理のコードを記述し、`calculate_total_price()`という関数にまとめることができます。
関数を使い分けることで、コードを整理し、再利用性を高めることができます。
<br>

 
<br>**・コメントをうまく使う**
コードだけだと分かりにくいところは、コメントで説明しましょう。
ただし、コメントでコードの動きをすべて説明するのは適切ではありません。
そもそもコード自体が分かりやすくなるように、名前、構造、処理の順番などを工夫しましょう。
<br>

※コメントって？
コメントは、コードの動作や意図を説明するためのメモ書きのようなものです。
プログラミング言語によって書き方が異なりますが、`//`や`#`などの記号を使って記述します。
例えば、`// この関数は、ユーザーの年齢を計算します`のような感じです。
<br>
<br>**・インデントを揃える**
インデントを揃えると、コードの構造が整理されて見やすくなります。

※インデントって？
インデントとは、行頭に空白を入れて、コードを字下げすることです。
インデントを使うことで、コードの構造を視覚的に表現し、読みやすくすることができます。

<br>**・空白行を入れる**
適度に空白行を入れると、コードが読みやすくなります。



<br><br>
## まとめ
今回は、「リーダブルコード」の1章を、初心者なりにまとめてみました。

まだコードの内容を完全に理解するのは難しいですが、「リーダブルコード」を読んで、読みやすいコードを書くことの重要性を改めて認識しました。

これからエンジニアとして、読みやすいコードを心がけ、
質の高いシステム開発に貢献していきたいと思っています。


<br>次回は、2章「名前に情報を詰め込む」についてまとめます。
Genesis実行環境の構築

## はじめに
　こんにちは。まっちゃ。です。:tea:
　今回は、物理シミュレータで話題となっている「Genesis」の環境構築についてまとめていきます。  

#### なぜ重要か
環境構築において、エラーが発生した箇所の対応策を共有するため

## 目次
- Genesisとは
- 環境構築
    - パッケージのインストール
    - リポジトリの複製
    - サンプルコードの実行
    - エラー対応
- まとめ

## Genesisとは
https://genesis-world.readthedocs.io/ja/latest/

汎用的な物理プラットフォームです。以下のような特徴をもちます。
- 多種多様な物理現象がシミュレート可能
- 軽量かつ超高速
- ユーザーが入力する自然言語の説明を様々な形式のデータに変換

## 環境構築
以下に示す4つの手順で進めていきます。ここでは、wsl上に環境構築を行い、公式のレポジトリにある"hello_genesis.py"をサンプルコードとして実行していきます。
- パッケージのインストール
- リポジトリの複製
- サンプルコードの実行
- エラー対応

### 【前提】
環境を構築する上で、以下に示す2つを前提としています。
- wsl環境上にpyenv, poetryが導入済であること
- GPUが使用できる環境を構築済であること（本記事では、CUDA12.1で構築済とします。）

### パッケージのインストール
1. 任意の空きフォルダを作成
2. pyenvでインストールされているPythonのバージョンを確認  
`pyenv versions`
3. 1.で作成したフォルダに移動し、構築環境のPythonのバージョンを指定（2.で確認したバージョンを入力）  
`pyenv local 3.XX.XX`
4. pyproject.tomlを作成  
`poetry init`
5. フォルダ内に仮想環境を作成（2.で確認したバージョンを入力）  
`poetry env use 3.XX.XX`
6. GPU版Pytorchをインストール  
`poetry source add torch_cu121 --priority=explicit https://download.pytorch.org/whl/cu121`
`poetry add torch torchvision torchaudio --source torch_cu121`  
【参考】
[GPU版のPytorchのインストール](https://zenn.dev/zerebom/articles/b338784c8ac76a)
7. genesisパッケージをインストール  
`poetry add genesis-world`

### リポジトリの複製
1. Genesisのレポジトリを複製  
`git close https://github.com/Genesis-Embodied-AI/Genesis.git`

### サンプルコードの実行
1. 「パッケージのインストール」5.で作成した仮想環境をactivateして、Genesisフォルダに移動し、サンプルコードを実行  
`python examples/tutorials/hello_genesis.py`

<br>
エラーの発生がなく、アームが自然に倒れる画面が表示されれば、ここで環境構築完了です。

### エラー対応
ここでは、サンプルコードを実行した際に遭遇した2つのエラーと解決方法について記載します。

#### エラー①　実行時に画面がポップアップされるが、黒い画面で何も映らない  
ターミナル上では"OpenGL.error.GLError"が発生
- pyopenglを3.1.5にダウングレード（genesis-worldを入れた時点で3.1.7が導入されていました。）
`poetry add pyopengl==3.1.5`

【参考】

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

#### エラー②　GPU使用時(`gs.init(backend=gs.gpu)`)にプロセスが中断される  
ターミナル上では以下のエラーが発生  
```
[cuda_driver.h:operator()@92] CUDA Error CUDA_ERROR_NO_DEVICE: no CUDA-capable device is detected while calling init (cuInit)  
```
- パスを追加
"~/.bashrc"に`export LD_LIBRARY_PATH=/usr/lib/wsl/lib:$LD_LIBRARY_PATH`を記載

【参考】

https://github.com/Genesis-Embodied-AI/Genesis/issues/187

## まとめ
　今回は「Genesis」実行環境の構築について、まとめてきました。  
　ロボットのシミュレーションというと専用のハード-ソフトを用いて行う認識だったので、「Genesis」を用いることで専用の機器を準備せず実行することが可能となり、かつ制御が簡単であるというのは驚きました。  
　次回以降で、Genesisの詳細な使用方法をキャッチアップしていこうと思います。
自己紹介＆投稿内容の考え方

# 自己紹介
ささきさくらです。名前の半分が「さ」です。
4年くらいServiceNowをやっています。
Qiitaはいつも見る専門だったのですが、業務で発生した細かい気づきをシェアして少しでも同じ悩みや調査で課題を抱える人に貢献できればと思い、アカウントをつくりました！
あとは、自身の備忘もかねて。（前も調べたこと毎回調べてから作業しちゃってる…とかざらにあるので。）

# 投稿内容の考え方
主にServiceNow関連の話が大部分を占めますが、
ServiceNowに限らずエンジニア作業におけるTipsなども適宜載せていこうと思ってます。

またなにか考え方などのUpdateがあれば、この自己紹介を更新していきます。
（最終更新：2025/01/19）
Dockerコンテナのタイムゾーン変更

## タイムゾーンを変更する方法

いくつかタイムゾーンを変更する方法はあります。
ubuntuにてタイムゾーンを変更する方法をまずは記載します。

## TZ環境変数で変更

```bash
docker run -it --rm -e TZ=Asia/Tokyo
```

## docker-composeで指定する方法

```yaml
service:
    httpd:
        environment:
            TZ= Asia/Tokyo
```
## /etc/localtimeを変更

TimeZone環境変数で変わらないイメージがある
その場合、/etc/localtimeを変更する

```bash

docker run --rm -it -v /etc/localtime:/etc/localtime:ro ubuntu:xenial-20190610 bash

```
DartでJavaScriptライブラリをもっと手軽に扱いたい

## 概要

DartからJavaScriptのライブラリにアクセスするためには基本的にDart専用の型定義のようなものを書くのが原則なんですが、TypeScriptの.d.tsと違い、誰も使ってないので全く揃っていない。

間の悪いことにGoogleはDart3.3からこの型定義の仕様を大幅に変えてしまったので、.d.tsからの変換ツールも軒並み更新を余儀なくされたもののどれも更新・対応する気配がまるで見えないという状況。

## とりあえず

型厳密にしたい気持ちはわかるんですが、このままではずっと机上の空論のままなので、型厳密のことはとりあえず忘れて普通にJavaScriptのようにとりあえず存在すればglobalThisから.で繋いだらメンバにアクセスできるような感じでJavaScriptライブラリを使いたい。

## 解決策

Dartのすべての基本クラスであるObjectには`noSuchMethod`というメンバが登録されており、これをオーバーライドすると(dynamic型経由で)存在しないメンバにアクセスしようとしたときに独自の処理ができるようになっているらしい。

意図的にどんなメンバにアクセスしようとしたかを単純に取得はできなくなってるっぽいが、今のところは特定の前後の文字列を削除するだけで対応できるみたい。

一応、dart/jsにはJavaScriptオブジェクトに対して文字列で名前を指定して関数やコンストラクタを呼び出したり
プロパティを取得したりする関数はあるのでそれを`noSuchMethod`から呼び出すことでそれっぽいことができるんじゃないかと。


## 成果物

いろいろ機能を付け足したら思った以上に複雑になった。

https://github.com/uniras/dollerJS/blob/main/dollarjs.dart
preferenceDataStore実装方法

# はじめに
今回はSharedPreferenceの代わりとなるpreferenceDataSoterの実装方法を紹介してきます
### 実装
```kotlin
// まずはデータストレージを作成
private const val PREFERENCES_NAME = "preference"
private val Context.dataStore by preferencesDataStore(PREFERENCES_NAME)

@Singleton
internal class DataStore @Inject constructor(
    @ApplicationContext context: Context,
    @ApplicationScope private val externalScope: CoroutineScope,
) {
    private val dataStore = context.dataStore

    private val dataFlow = dataStore.data
        .catch { ex -> throw ex }
        .map { preference ->
            val data = preference[KEY] ?: return@map null
            DataClass(data = data)
        }
        .stateIn(externalScope, SharingStarted.Eagerly, null)

    fun getDataFlow(): Flow<DataClass?> = dataFlow

    fun saveData(data: DataClass) {
        externalScope.launch {
            dataStore.edit { prefs ->
                prefs[KEY] = data.data
            }
        }
    }

    companion object {
    // 型によってstringPreferencesKeyになったりする
        private val KEY = booleanPreferencesKey("key")
    }
}
```

### 最後に
大まかではありますが、上記を参考にすればたいていは作れるかと思います
どなたかのお役に立てれば幸いです
Mybatis resultType:"Integer"と"int"の違い

以下のようなメールアドレスをもとにユーザーの存在チェックを行うメソッドを例に挙げる。

```java:UserMapper.xml
<select id="verifyExistsUser1" resultType="Integer">
    SELECT 1
    FROM account
    WHERE email = #{email}
    LIMIT 1
  </select>

  <select id="verifyExistsUser2" resultType="int">
    SELECT 1
    FROM account
    WHERE email = #{email}
    LIMIT 1
  </select>
  ```
  
  ```java:UserService.java
  private void test1(String email) {
      // 存在する場合は1、存在しない場合はNULLが返却される
      Integer result1 = userMapper.verifyExistsUser1(email);
      if (Objects.isNull(result1)) {
        throw new BussinessException( HttpStatus.NOT_FOUND, "User with email " + email + " not found")
      }

      // 存在する場合は1、存在しない場合は0が返却される
      int result2 = userMapper.verifyExistsUser2(email);
      if (result2 == 0) {
        throw new BussinessException( HttpStatus.NOT_FOUND, "User with email " + email + " not found")
      }
  }
  ```

  単純にInteger型で返却されるか、int型で返却されるかの違いだが、結果がNULLの場合の返却値は異なるので、エラー処理するときはその点考慮すること
Reversed LinkedList

# Intro
単一リンクリスト（Singly Linked List）は、各ノードがデータと次のノードへの参照（ポインタ）を持つ線形データ構造です。 この構造は、動的にサイズを調整でき、要素の挿入や削除が容易であるという利点があります。

**単一リンクリストの構造:**

- **ノード（Node）**: 各ノードは以下の2つの部分で構成されます。
  1. **データ（Data）**: ノードが保持する値。
  2. **次への参照（Next）**: 次のノードを指すポインタ。

リストの開始点は「ヘッド（Head）」と呼ばれ、リストの終端は次のノードが存在しないことで示されます。

**部分反転（Reverse）操作:**

単一リンクリスト内の特定の区間のノードを反転させる操作は、以下の手順で行われます。

1. **ダミーノードの作成**: ヘッドの前にダミーノードを追加し、境界条件を簡単に処理できるようにします。
2. **ポインタの設定**: 反転区間の開始位置まで移動するためのポインタを設定します。
3. **部分リストの反転**: 設定したポインタを用いて、指定された区間のノードを反転させます。
4. **リストの再接続**: 反転された部分リストを元のリストと再接続します。

この操作により、リストの特定の区間を効率的に反転させることができます。

**例として、以下のコードは単一リンクリスト内の指定された区間 `[left, right]` のノードを反転させる機能を実装しています。**

```java
/**
 * 単一リンクリストのノードの定義
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode reverseBetween(ListNode head, int left, int right) {
        // 例外処理: headがnull、またはleftとrightが同じ場合
        if (head == null || left == right) {
            return head;
        }

        // ダミーノードの作成
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode prev = dummy;

        // leftの前までprevを移動
        for (int i = 0; i < left - 1; i++) {
            prev = prev.next;
        }

        // 反転開始ノードとその次のノードを設定
        ListNode start = prev.next;
        ListNode then = start.next;

        // 部分リストの反転
        for (int i = 0; i < right - left; i++) {
            start.next = then.next;
            then.next = prev.next;
            prev.next = then;
            then = start.next;
        }

        return dummy.next;
    }
}
```

このコードは、単一リンクリスト内の指定された区間 `[left, right]` のノードを反転させる機能を実装しています。 ダミーノードを使用して境界条件を処理し、ポインタ操作を通じて部分リストを効率的に反転させます。
ブラウザだけでReact(TSX)を実行する

## 概要

ReactのTSXは直接ブラウザで実行できないのでJavaScriptへのトランスパイルが必要なんですが、Babel Standaloneはブラウザ上で動いてTSXのトランスパイルが可能なので、これを利用してブラウザだけで実行させたい。

## 問題

HTML内に直接書いたコードであればその内容を文字列として取得して単純にBabelでトランスパイルすれば十分なのですが、script要素のsrc属性で指定したコードや、importで取り込んだコードはそういうわけにはいきません。拡張子が違うと怒られたりそれをどうにかしてもトランスパイルなしで直接実行しようとしてエラーになったりします。

## 解決策

ServiceWokerを使えばHTTPリクエストをフックしてブラウザ内で独自処理やレスポンス返却ができるので、TSXへのリクエストが有ればトランスパイルしてJavaScriptとしてレスポンスを返すようにすればsrc属性やimport経由でロードしたTSXもトランスパイルが可能なのではないか？

## 結果

できました。

https://github.com/uniras/TinyReactSW

本体はReactライブラリを読んで初期化し、App.tsxのAppコンポーネントをレンダリングする`index.html`と、リクエストを受けてJavaScriptにトランスパイルする`sw.js`の2つだけです。主だったライブラリはすべてCDNから取り込んでいるのでインストール作業は必要ありません。

※ただし、VSCodeでコーディングする場合は何もしないと型宣言がないというエラーが煩いので、それが嫌ならnpmで`@types/react`をインストールする必要があるかもしれません。
ラムダ計算:再帰関数

再帰関数に考える前に以下のラムダ関数$\textbf{Y}$について考えてみる。

$$\textbf{Y}\equiv(\lambda y.(\lambda x.y(xx))(\lambda x.y(xx)))$$

関数$R$に$\textbf{Y}$を適用すると
$$\textbf{Y}R\equiv(\lambda x.R(xx))(\lambda x.R(xx))$$

となるが、更にreduceを続けると、
$\textbf{Y}R
\rightarrow R(\lambda x.R(xx))(\lambda x.R(xx))
\rightarrow R(\textbf{Y}R)$つまり
$$\textbf{Y}R\rightarrow R(\textbf{Y}R)$$

となる。これは関数$R$が第一変数として再帰呼び出し$\textbf{Y}R$で評価されている。
お名前.comでメールアドレスを作成



#### 経緯

とあるサービスを利用したくていつものアドレスを使用したら、
「フリーアドレスは使用できません。」とはじかれた為、ドメインを取得してメールアドレスを作成することになった。


##### お名前メールのお申込み

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1399728/7ba0f5a9-c846-5435-8fac-cf507defbfb0.png)


お名前メールから「ドメインを新規で申し込む」を選択。（既にドメインを持っている場合は契約済のドメインで申し込む）

その後プランを選択してドメイン名を入力。
希望のドメインを選択して申し込みをする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1399728/c7d8a9d7-c465-30d9-5738-2a2ce761331a.png)

その後数分から数十分待つと電話認証のメールが届くため、認証を終わらせる。


トップに遷移して該当のお名前メールのログインを押下する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1399728/0924d6ce-5e9b-4623-1f3e-c43fbba0eaeb.png)



「はじめる」を選択して、メールアドレスとパスワードを設定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1399728/c82c92c6-6bbe-b4e4-d389-1f87008f36ee.png)



作成完了後に表示された受信メールサーバーと送信サーバーをコピーする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1399728/85e073c4-e6ed-c399-36a0-0c935dace371.png)



#### outlookに設定する

アカウント設定から新規を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1399728/a11c896c-0a3e-b36d-f00c-adb9ba5b8291.png)

先ほどお名前.comで作成したメールアドレスを入力し、「自分で自分のアカウントを手動で設定」を有効にして接続する。

POPを選択して先ほどコピーした受信サーバーと送信サーバーをコピペして、ポートも入力する。
「このサーバーでは暗号化された接続（SSL/TLS）が必要」を有効にする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1399728/4ff6b892-6131-faf9-e773-9d407ecec88c.png)

次へを押下してパスワードを入力して接続で完了




（なぜかIMAPで設定はうまくいかなかったためPOPにしました。。。）
AtCoder Beginner Contest 389 振り返り

ABC389の振り返りです。最近振り返りさぼっててすみません。

## 結果

ABCの3完でした。

![スクリーンショット 2025-01-19 20.35.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167729/b691c0e8-9534-6def-9fa0-f905bd0de7ae.png)

![スクリーンショット 2025-01-19 20.34.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167729/81660356-ab60-8dc7-376f-e0d7d7aa1eed.png)

## ふりかえり

### A問題

- 問題
  - https://atcoder.jp/contests/abc389/tasks/abc389_a
- 回答
  - https://atcoder.jp/contests/abc389/submissions/61791019

CharからIntに変換する関数を作りました。

```haskell
main = do
  ans <- do
    [x, 'x', y] <- getLine
    return $ charToInt x * charToInt y

  print ans

charToInt :: Char -> Int
charToInt c = ord c - ord '0'
```

`digitToInt`で解くこともできます。こっちの方がスマートです。

```haskell
main :: IO ()
main = do
  s <- map digitToInt <$> getLine

  print $ head s * last s
```

### B問題

- 問題
  - https://atcoder.jp/contests/abc389/tasks/abc389_b
- 回答
  - https://atcoder.jp/contests/abc389/submissions/61797779

1から掛けていって、`x`と同じになったら返します。

```haskell
main :: IO ()
main = do
  x <- readLn @Int

  print $ f x

f :: Int -> Int
f x = go 1 1
  where
    go n ans
      | ans == x = n - 1
      | ans < x = go (n + 1) (ans * n)
      | otherwise = error "invalid pattern"
```

### C問題

- 問題
  - https://atcoder.jp/contests/abc389/tasks/abc389_c
- 回答
  - https://atcoder.jp/contests/abc389/submissions/61815034

問題文通り、[Data.Sequence](https://hackage.haskell.org/package/containers-0.7/docs/Data-Sequence.html)をキューとして使って解いていきます。先頭からヘビを除外した場合、全てのヘビから除外するヘビの長さを引くと時間がかかってしまうので、削除した値を保持しておきます。
同様に、計算量を減らすためにヘビの追加時に`全体の長さ+追加するヘビの長さ`としたいので、全体のヘビの長さも保持しておきます。

```haskell
main :: IO ()
main = do
  q <- readLn @Int
  qs <- replicateM q getInts

  f qs

f = foldM_ (flip go) (Seq.empty, 0, 0)
  where
    go [1, l] (seq, minus, tail) = return (seq Seq.|> (tail, l), minus, l + tail)
    go [2] (seq, minus, tail) = do
      case Seq.viewl seq of
        Seq.EmptyL -> error "empty queue"
        (_, l) Seq.:< seq' -> return (seq', minus + l, tail)
    go [3, k] (seq, minus, tail) = do
      print $ fst (Seq.index seq (k - 1)) - minus
      return (seq, minus, tail)
    go _ _ = error "invalid pattern"    
```

ちなみに、この問題は`k番目のヘビの頭の座標 - 先頭のヘビの頭の座標`で解くこともできます。
このように解くと、除外したヘビの長さの合計や全体のヘビの長さを保持しておく必要ないのでよりシンプルに解けます。

ソースはこのような感じです。

```haskell
main :: IO ()
main = do
  q <- readLn @Int
  qs <- replicateM q getInts

  f qs

f :: [[Int]] -> IO ()
f = foldM_ go Seq.empty
  where
    go seq [1, l] = do
      let tail = case Seq.viewr seq of
            Seq.EmptyR -> 0
            _ :> (_, tail) -> tail
      return $ seq :|> (tail, tail + l)
    go seq [2] = do
      case Seq.viewl seq of
        Seq.EmptyL -> error "empty queue"
        _ :< seq' -> return seq'
    go seq [3, k] = do
      let head = case Seq.viewl seq of
            Seq.EmptyL -> error "empty queue"
            (head, _) :< _ -> head
          khead = fst (Seq.index seq (k - 1))
      print $ khead - head
      return seq
    go _ _ = error "invalid pattern"
```

## 全体を振り返って

今回調子よかったので、次回からもこんな感じで解いていければと思います！
wslで個人的によく使うコマンド一覧（インストール、削除、デフォルト設定等基本的な部分）

## 毎回調べるのが面倒なので、よく使うものをまとめました。
特に目新しい情報はありませんが、とりあえずここにあるコマンドを使えれば、wslでLinuxを動かすことはできると思います。

## よく使うコマンド一覧
- `wsl --list`
インストール済みのLinuxディストリビューション名が分かる。デフォルトのディストリビューション（wsl起動時に立ち上がるLinuxのこと）名の横には **（既定）** と書かれている。
- `wsl --list --verbose`
ディストリビューション名に加えて、ステータスやバージョンも分かる。
- `wsl --list --online`
インストール可能なディストリビューションが分かる。
- `wsl --install <ディストリビューション名>`
インストールする。
- `wsl --set-default <ディストリビューション名>`
デフォルトのディストリビューションを設定する。
- `wsl --unregister <ディストリビューション名>`
ディストリビューションを削除する。
GASからGoogle AI Studioを呼び出す

# 目的
Google AI StudioとGoogleAPPsScript(GAS)を組み合わせたスクリプトが無かったので作ってみました。

# GoogleAIStudioとは
Google AI Studioは、Googleが提供しているAIモデルを手軽に試したり、プロトタイプを作成したりできるツールです。
最新のAIモデルの利用、APIの発行が無料でできることが魅力です。
(参考：https://ai.google.dev/aistudio?hl=ja)

~~これがあれば、有料版のGeminiは不要・・・~~

今回はこのAPIを用いてGASと連携させることを考えます。

# 事前準備
Google AI StudioでAPIキーを発行

# GASでのAPIキーの保管
一般にスクリプト内にAPIキーそのものを保管するのは望ましくありません。
そのため、GASの機能でAPIキーを保管し、スクリプトで呼び出す形式にします。

GASのProject setting⇒Script Propertiesで保管をしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3989754/945cb68f-1239-bc78-37e0-e52a3cfaeb06.png)


# GASでのスクリプト
※Geminiに作ってもらいました。

```js:GAS
function generateAIContent() {
  const API_KEY = PropertiesService.getScriptProperties().getProperty('AI_studio_Key');
  if (!API_KEY) {
    Logger.log("APIキーが設定されていません。スクリプトプロパティで設定してください。");
    return;
  }

  const modelName = "gemini-1.5-flash"; // モデル名
  const prompt = "AIって何"; // プロンプト
  const apiUrl = "https://generativelanguage.googleapis.com/v1beta/models/" + modelName + ":generateContent"; // APIエンドポイント

  // リクエストボディ
  const requestBody = {
    contents: [{
      parts: [{ text: prompt }]
    }]
  };

  // HTTPリクエストを送信
  const options = {
    method: 'POST',
    contentType: 'application/json',
    headers: {
      'x-goog-api-key': API_KEY,
    },
    payload: JSON.stringify(requestBody),
    muteHttpExceptions: true
  };

  const response = UrlFetchApp.fetch(apiUrl, options);
  const responseCode = response.getResponseCode();

  if (responseCode === 200) {
    const json = JSON.parse(response.getContentText());
    const generatedText = json.candidates[0].content.parts[0].text;
    Logger.log(generatedText);
    return generatedText;
  } else {
    Logger.log("エラーが発生しました。コード: " + responseCode + " 内容: " + response.getContentText());
    return null;
  }
}
```
# 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3989754/d7ffbe09-5382-3e1a-61bb-bcf255398f46.png)

# 今後の展望

今回は簡単なスクリプトで実行ログに結果を表示するところまで実施しました。
外部のAPIを容易に利用可能なので、組み合わせて色々遊ぼうと思います。

無料でこれだけ出来て感激！