OmniAICreator/Qiita-1.07M huggingface dataset:
WordPressでマルチサイトを構築する手順

# WordPressのマルチサイト化するメリット・デメリット
| No. | メリット |
|:-:|:-:|
| ①  | 開発や管理が効率的になる  |
| ②  | サーバー容量の節約になる |
| ③  |ドメイン費用を節約できる   |


| No. | デメリット |
|:-:|:-:|
| ①  |テーマやプラグインによっては未対応  |
| ②  |エラーが全ウェブサイトに影響する |
| ③  |ウェブサイトが重くなる   |

# WordPressのマルチサイトの種類
| No. | 種類 | 例 | 
|:-:|:-:|:-:|
| ①  |サブディレクトリ型  |https://xxx.com/test1 <br>https://xxx.com/test2<br>https://xxx.com/test3 |
| ②  |サブドメイン型 |https://test1.xxx.com/ <br> https://test2.xxx.com/ <br>https://test3.xxx.com/ 
| ③  |別ドメイン型 |https://test1.com/ <br>https://test2.com/ <br>https://test3.com/ |

# WordPressでマルチサイトを構築する手順
#### 1.wp-config.phpを編集
```php
/* Multisite */
define( 'WP_ALLOW_MULTISITE', true );
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/31a0e541-eb7e-a8d3-ec81-7e0e715985ce.png)

#### 2.ネットワークの設定を確認
    ・1．「ツール」→「サイトネットワークの設置」を開く
    ・2.  サブディレクトリ型かサブドメイン型を選択
    ・3.  サイトネットワーク名を入力    
    ・4.  インストールをクリック       
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/666b578c-5b5a-86ff-43ee-33a7a9c29e19.png)


#### 3.ネットワークをインストール
2つのファイルに追記する内容が表示されるので、このまま画面を閉じないようにしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/1635edce-10af-c081-95d1-2758d46ed079.png)
#### 4..htaccessとwp-config.phpに追記
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/8d6f047e-f518-9a1c-49ca-338e41b43c96.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/42edb6cc-ad80-5c70-c358-f2483a81b6d9.png)

#### 5.再度ログインを行う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/465ca8c2-c338-9a3f-8c10-382f25985a1b.png)

#### 6.サブディレクトリ用のサイトを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/0830d808-2763-b4f2-23bf-7cb1ed5a08a4.png)

#### 7.サイトを追加する
画面左上「参加サイト」→「サイトネットワーク管理」→「サイト」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/6911467e-ad40-66fc-bfb5-0abb9a2747ab.png)
アクセス制御がなぜ必要か？

## アクセス制御について
アクセス制御は「承認済みユーザーしか使えない機能」のことで、部外者や権限のないユーザーからの不正アクセスを防ぎます。
アプリケーション側でユーザー識別を行うから、ユーザーが認証情報を入力する他に、特別な操作をする必要はありません。
そしてアクセス制御は、「認証・認可・監査」の3つの機能で成り立っています。


## アクセス制御の機能について
**①認証**
本人しか知らない情報を使って本人確認を行うことで、パスワードの他にアプリを使ったセキュリティコードや、顔や指紋を使った生体認証もよく使われる。

**②認可**
利用する機能へのアクセス権限を与えることで、無料ユーザーの利用範囲を制限することができる。画面上の操作以外に、URLから直接アクセスするのを禁止するなどのアクセス制限も考慮する必要がある。

![スクリーンショット 2023-11-18 18.57.50.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3568357/4eb29c3d-f493-8d4e-3153-a43ac2ce4814.jpeg)

ログインしていない状態で、ユーザーページにアクセスしようとすると・・

![スクリーンショット 2023-11-18 19.00.02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3568357/2084dbd7-a390-4204-c80d-cd9b8fbcf221.jpeg)

ユーザーページのアクセスを禁止され、ログインする様催促される

**③監査**
あらゆるユーザーの利用状況をログに記録し、そのログからセキュリティ問題が無いかを調査できる。監査ログがどんな機能を持つかは、改めて投稿しようと思います。


## 調べてみて分かったこと
webアプリの機能を追加してユーザーを獲得する他に、不正アクセスも考慮してアクセス制御を行う必要があるんですね。

「どんなユーザーがいて、どの範囲まで利用できる様にするか」

それを意識して、開発アプリにアクセス制御を入れようと思います。
AttributeError: 'TransformListener' object has no attribute 'tf_sub'

# 問題
## 状況
- Python経由でROSを使用
- TFをlistenしようとしていた

## コード
```Python
cmd_vel_pub = rospy.Publisher("/hoge/command_velocity", Twist, queue_size = 1)
tflistener= tf.TransformListener()
twist = Twist()
rate = rospy.Rate(control_hz)
```

## エラー
```Shell
Traceback (most recent call last):
  File "test.py", line 26, in <module>
    tflistener= tf.TransformListener()
  File "/opt/ros/noetic/lib/python3/dist-packages/tf/listener.py", line 367, in __init__
    self._listener = tf2_ros.TransformListener(self._buffer)
  File "/opt/ros/noetic/lib/python3/dist-packages/tf2_ros/transform_listener.py", line 54, in __init__
    self.last_update = rospy.Time.now()
  File "/opt/ros/noetic/lib/python3/dist-packages/rospy/rostime.py", line 155, in now
    return get_rostime()
  File "/opt/ros/noetic/lib/python3/dist-packages/rospy/rostime.py", line 190, in get_rostime
    raise rospy.exceptions.ROSInitException("time is not initialized. Have you called init_node()?")
rospy.exceptions.ROSInitException: time is not initialized. Have you called init_node()?
Exception ignored in: <function TransformListener.__del__ at 0x7fd240de4670>
Traceback (most recent call last):
  File "/opt/ros/noetic/lib/python3/dist-packages/tf2_ros/transform_listener.py", line 60, in __del__
    self.unregister()
  File "/opt/ros/noetic/lib/python3/dist-packages/tf2_ros/transform_listener.py", line 66, in unregister
    self.tf_sub.unregister()
AttributeError: 'TransformListener' object has no attribute 'tf_sub'

```

# 解決方法
ちゃんとinit_nodeする
```python
rospy.init_node('atarimae_taisou')
```

# 所感
あたりまえすぎたが最後のエラーだけ見てもミスにすぐ気づけなかったため。（よく読めばHave you called init_node()?と言われているが）
【SQL】BigQueryの小さなtips

# BigQueryで使える小さなtips

見つけるごとに追加していきます。

## 期間を絞りたい時のBETWEEN

WHEREで期間を絞りたい時にはBETWEENを用いる。

e.g.)2000年4月1日生まれから2001年3月31日生まれのユーザを抽出する。
```:SQL

SELECT *
FROM `/labokgs_project/users`
WHERE birthdate BETWEEN 2000/04/01 AND 2001/03/31

```


## WHEREで数字にORを適用したい時
IN ()を使うことで解決できる。

e.g.)クラスが１組、３組、５組の生徒を抽出したい。
```:SQL

SELECT name
FROM `school/students`
WHERE class_id IN (1, 3, 5)

```


## GROUP BYをした時に、それ以外のカラムをSELECTしたい。

#### ANY_VALUEとは？
GROUP BYを使って、集計を行った際の結果集計してない列を含めることができるようになる集計関数。


```:SQL

SELECT prefecture_name, ANY_VALUE(population)
FROM prefectures
GROUP BY prefecture_name

```
【SQL】何度も使うテーブルはWITH句を活用する

## 問題の背景


SQLである初心者は、使いたいテーブルがあったらBigQuery上で結合を行った後一つ一つテーブルやビューとして保存してからJOINを行っていた。
これでは後から見た時にどのテーブルを結合したのか、いちいち探しにいく必要がある。
作成したテーブルを今後も使うことがあるのであれば、それでも構わないが今回限りしか使わない、且つ今回は何度も使用するという場合はWITH句を使って一つのビューの中でテーブルを作ってしまうのが早い。

## WITH句の使い方。
WITH句はいわゆるサブクエリである。
記述方法は以下のようになる。
```:SQL
WITH テーブル名　AS （SELECT ... FROM ...）

```

より詳細な使い方としては以下のようになる。

今回はusersテーブルとusers_detailsという二つのテーブルを結合し、IDが1から１００までのユーザーを抽出したテーブル"target_users"とproductsテーブルとproducts_detailsテーブルを結合したテーブル"products"をWITH句で作成する。


```:SQL

WITH
    target_users AS (
        SELECT users.name, users.id, users_details.registered_at
        FROM `labokgs_project/users` users
        JOIN users_details users_details
        USING(id)
        WHERE id BETWEEN 1 and 100
        ),

    products AS (

        SELECT procuts.name, products.id, products_details.url
        FROM `labokgs_project/products` products
        JOIN products_details
        USING(id)

        )
SELECT ...
FROM ...

```
gitbashやCygwinでifortコマンド(Intel Fortran Compiler)を使う

Windowsで開発するプログラマはコマンドプロンプトなどPowerShell系環境よりWSLやCygwinやgitbashなどのLinux系環境を使う人々が多いでしょう
[参考：Windows でシェル スクリプトを実行する方法](https://mspoweruser.com/ja/different-ways-to-run-shell-script-files-on-windows/)

ところがIntel Fortran Compilerは`setvars.bat`というバッチファイルでコンパイル環境を用意するためPowerShell系環境を使うことを強制させられるという問題があります。

その解決のためifortコマンドのように動作するシェルスクリプトを作りました。
あなたの御用のためにお使いください

```ifort.sh
#!/usr/bin/env sh
# これはgitbashでコマンドプロンプトのようにifortを起動するためのスクリプトです
# ./ifort.sh -Qmkl -openmp hello.f90
# のようにコマンドプロンプトとの差異を感じずに使えます。
set -eux
#　この変数にインストールしたIntel Fortranの環境変数設定バッチファイルの起動コマンドを入れる
readonly IFORT_SETVARS_BAT='"C:\Program Files (x86)\Intel\oneAPI\setvars.bat" intel64 vs2022'
# IFORTを起動
echo "%ComSpec% /E:ON /C \" $IFORT_SETVARS_BAT & ifort $@\"" | cmd
```

`IFORT_SETVARS_BAT`に適切な`setvars.bat`の起動コマンドを入れてください
みればわかる通り、内部でcmd.exeを起動しています。

`./ifort.sh -Qmkl -openmp hello.f90`
のようにopenmpやmklを使うプログラムも通常のifortコマンドと同様に使用可能です。

よいBash生活 on Windowsを
【SQL】concatでURLのカラムを作成する。

## 問題の背景


Webサイト上の商品名と商品のURLをまとめたビューを作る必要があり、各商品のURLはURLの末尾がそれぞれの商品IDとなっている。

→URLのテンプレートと商品IDを使って、すべての商品のURLを作成してカラムを作りたい。


## concat()の使い方

concatは文字列と文字列を結合することができる。
CONCAT(文字列1, 文字列２）
文字列の部分に特定のテーブルのカラムを選択することで、特定の文字列とカラムを合わせた新しい文字列を作ることができる。

```:SQL

CONCAT("https://imazon.com/products/", product.id) AS product_url
```


以下のようなテーブルが作成される。

![スクリーンショット 2023-11-18 19.46.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1090582/3155b448-b7ed-dd6f-6222-7897fec37bcb.png)
[Ruby]シンボルとは何か。文字列との違いもはっきりさせたい。

ハッシュでよく使われるシンボルですが、ハッシュ以外でシンボルとシングルクオートが並んでいるコードを見た時、なぜ違う書き方をしているのか理解できないことがありました。
私にはどちらも同じものに見えており「そこ、シングルクオートで書いてしまえばいいのでは？」と思ったからです。
しかし、実際は**文字列に見えるようでシンボルと文字列は異なるものである**ということを知りました。
そこで、シンボルについての理解を深めるために、改めてまとめてみようと思いました。

## シンボルとは
```
# シンボルは:strを指す
str = :str
```
Rubyのリファレンスマニュアルには以下のように説明されています。
>シンボルを表すクラス。シンボルは任意の文字列と一対一に対応するオブジェクトです。

>Rubyの内部実装では、メソッド名や変数名、定数名、クラス名など の`名前'を整数で管理しています。これは名前を直接文字列として処理するよりも 速度面で有利だからです。そしてその整数をRubyのコード上で表現したものがシンボルです。(中略)シンボルは、ソース上では文字列のように見え、内部では整数として扱われる、両者を仲立ちするような存在です。

私が最初に理解につまずいてしまったのは、どうやら「シンボルの見た目が文字列のように見えてしまっていたこと」が原因だったようです。
そもそも、整数として扱われるシンボルと文字として扱われる文字列では、異なるオブジェクトであることがわかりました。

以上のことを踏まえ、文字列との比較もしながら、シンボルについてより詳しく書いていこうと思います。

### 1.Symbolクラスのオブジェクトである
シンボルはSymbolクラスのオブジェクト、文字列はStringクラスのオブジェクトです。

### 2.immutable(変更不可)である
Rubyでは、シンボルはimmutableなので[破壊的な変更](https://docs.ruby-lang.org/ja/latest/class/String.html)をすることができません。一方で、文字列はmutableなので破壊的な変更を加えることができます。
```ruby
str1 = 'str' 
str2 = :str

# .upcase!で全ての小文字を対応する大文字に置き換えた文字列を返す
str1.upcase! # => 'STR'
str2.upcase! # => NoMethodErrorが発生する
```
### 3.同値ならば必ず同一である
Rubyにおける同値性は、オブジェクトの一致/不一致に関わらず値が等しいことを、同一性は、オブジェクトが等しいことを意味しています。シンボルは、同値の場合同一であることが約束されます。
```ruby
#　同じ名前の文字列とシンボルから生成されるインスタンスを比較する
str1 = "str"
str2 = "str"
str3 = :str
str4 = :str

#　論理演算子==でお互いの値が一致するかを確かめる
puts str1 == str2 # =>true
puts str3 == str4 # =>true

#　.equal?でお互いのObject#object_idが一致するかを確かめる
# 二つのオブジェクトが同じかどうかがわかる
puts str1.equal?(str2) # =>false
puts str3.equal?(str4) # =>true
```

### 4.文字列よりも比較の処理が速い
シンボルは一度生成されると同じ領域を使用します。そのため、使用するたびに異なる領域を介す文字列よりも、メモリの効率がよく、処理の速度が速くなります。

## 補足
文字列自体をデータとして扱いたい場合は素直に文字列を使用した方がいいです。

## 結論
**・Symbolクラスのオブジェクトである**
**・immutable(変更不可)である**
**・同値ならば必ず同一である**
**・文字列よりも比較の処理が速い**

## 参考記事
[「Ruby 3.2 リファレンスマニュアル > Symbolクラス」](https://docs.ruby-lang.org/ja/latest/class/Symbol.html)
[「Ruby 3.2 リファレンスマニュアル > Stringクラス」](https://docs.ruby-lang.org/ja/latest/class/String.html)
[「Rubyの文字列とシンボルの違いをキッチリ説明できる人になりたい」](https://qiita.com/Kta-M/items/53a13ef60e14fcb41193)
[「Rubyのシンボルを詳しくまとめてみた。」](https://beck23.hatenablog.com/entry/2014/09/04/032453)
[「Rubyのシンボルを丁寧に理解する」](https://zenn.dev/kanoe/articles/352d78902c83e168db66)
[「【Ruby入門】コロン記号の意味とシンボルのやさしいまとめ！」](https://www.sejuku.net/blog/13094)
LoRaWANを試す - ゲートウェイ設置編

# はじめに

以前から気になっていたLoRaWAN環境が手の届くようになってきたので試してみようと思う。LoRaはWiFiやBluetoothのような特定小電力無線局の仲間で、環境によっては10km以上も電波が届くことがあるとのこと。

Semtech社のページにあるLoRaの位置付け

![](https://www.semtech.com/uploads/images/LoRa_Why_Range.png)

# 準備

LoRaWANの利用には、端末の他に、ゲートウェイ、ネットワークサーバーの三者が登場する。まず、ゲートウェイ、ネットワークサーバーの準備から始める。今回はネットワークサーバーとしてAWS IoTを利用する。ゲートウェイは低いレイヤーでの中継を行う。

![](https://www.mdpi.com/telecom/telecom-03-00018/article_deploy/html/images/telecom-03-00018-g001.png)


## ゲートウェイ

今回使用するゲートウェイはこちら。日本仕様はACアダプターが付属しないので、別途購入の必要がある。

https://www.seeedstudio.com/SenseCAP-Multi-Platform-LoRaWAN-Indoor-Gateway-SX1302-AS923-Japan-p-5649.html

https://www.marutsu.co.jp/pc/i/2720302/

https://www.marutsu.co.jp/pc/i/1319372/

#### 設定

イーサネットに繋げるとDHCPでIPアドレスを取得してそのままネットワーク（LAN）に接続する。
WiFiで接続したい場合は、電源の横にあるボタンを5秒以上長押しすると、ステーションモードで起動するのでPCなどからWiFiで接続して SenseCAP_XXXXXX のAPを見つけて設定する。APのパスワードは 12345678 。
ログイン情報は本体の裏側に記載されている。

クイックスタートのガイドはこちら

https://files.seeedstudio.com/products/SenseCAP/M2_Multi-Platform_Gateway/Quick_Start_for_SenseCAP_Gateway_&_Sensors.pdf

## AWS IoT Core for LoRaWAN

ゲートウェイをネットワーク（LAN）に接続したら、ゲートウェイをAWS IoT Core for LoRaWANに登録する。基本的には以下のドキュメントに従ってAWS IoTを設定する。

https://files.seeedstudio.com/products/SenseCAP/M2_Multi-Platform_Gateway/Connect%20M2%20Multi-Platform%20Gateway%20to%20AWS%20IoT.pdf

以下の流れ

- AWSコンソールにログイン
- サービス一覧から IoT > IoT Core を選択して AWS IoT に移動
- LPWAN デバイス > ゲートウェイ に移動し、「ゲートウェイを追加」。EUIは筐体の裏に記載
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555397/302c81d5-2ffb-afc6-5896-a78f3da0a902.png)

- 証明書の作成とダウンロード。上下のボタンを押してそれぞれダウンロード計4ファイル
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555397/98245a8b-3874-4aab-23ee-4007d90496ae.png)

- IoTWirelessGatewayCertManagerRole を付与する。初回はボタンを押してロールを作成する

## ゲートウェイに証明書を設定

- ゲートウェイのコンソールにログイン
- メニューの LoRa > LoRa Network から、AWS IoTでダウンロードした証明書を登録する
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555397/aac00bc7-f7c5-1c3b-5188-538cc8db016a.png)

## AWS IoTに戻って接続を確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555397/1713e8cc-e6e7-6a61-8ba7-44fc30030138.png)

# ゲートウェイの準備完了

以上でゲートウェイを設置できた
【Unity】自作ノードベースの会話システムパッケージ「ConversationGraph」の紹介

# ConversationGraphとは
私が開発した、ノードベースで、RPGやノベルゲームで使われる会話を簡単に作れるUnity Packageです。

## コンセプト
バージョン管理もできるエンジニアとデザイナーが手軽に連携して会話シーン作れるシステム
### 利用想定ゲームジャンル
RPG, 3Dアクションなど。
今後ノベルゲームなどに対して有効な手段を追加予定です。詳しくは後述します。

## リポジトリ
https://github.com/PrashaltGames/Unity-ConversationGraph

:::note warn
ごめんなさい！
現在ConversationGraph-v2と称してコードを１から書き直しています。
そのためリポジトリは非公開となっています。
:::

# 特徴
### 1.独自のプロパティシステム
`HasConversationProperty`と`ConversationProperty`という２つの属性が用意されており、これを静的なプロパティもしくはフィールドに付与するとプロパティとして登録されます。

ConversationGraph中のテキストに`{PropertyName}`とすると、会話時にプロパティの値に置換されます。

また、Bool型のプロパティはノードとしても使用でき、Branchノードでフラグ管理をすることができます。

この属性を用いたプロパティシステムはほかのGraph系ツールにはありません。（たぶん）
Unity 6でリリース予定のUXMLの機能と似ているかもしれません。

### 2.互換性の高いSubGraphシステム
このパッケージにもShader GraphなどのSubGraphと同じような仕組みが導入されています。

ただし、このパッケージにおけるSubGraphは専用のアセットがあるわけではなく、同一アセット以外のすべてのConversationGraph AssetがSubGraphとして利用できます。

SubGraphの多重入れ子関係も可能です。

### 3.サポート
Input Managerだけでなく、Input Systemに対応しています。

当初はUI Toolkitの対応も考えましたが、TextMeshProのアニメーションに対応していなかったので、対応を見送りました。
アニメーションに対応次第検討します。

### 4. スッキリとしたグラフ
なるべくノード数が少なくなるように一つのノードで複数のテキストを持てるなどの工夫がされています。

### 5.アニメーションシステム
[MagicTween](https://github.com/AnnulusGames/MagicTween)を利用したアニメーションシステムを搭載しています。
また、ソースジェネレーターも利用しており、こだわりポイントです。

# 今後の展望
### GraphのUXについて
今後は、Unityはノードベースツールの開発システムである「GraphTools Foundation」の開発をしています。
正式にエディターに組み込まれた際はこれに移行し、より深くノードツールを発展させようと考えています。

現在は、なるべく依存性を下げるためGraphView（現在組み込まれているノードベースツールの開発システム）に深く足を入れないように開発しています。

これによって以下の機能の実装を見送りました。移行次第実装します。
- [ ]  グラフでプロパティなどを編集した際に変更されたことにならない（=閉じるときに警告が出ない）
- [ ]  SubGraphをクリックするとそのGraphAssetを別Windowで開くように
- [ ]  Propertyを使ったときに、正しく入力されているかGraphで分かるように

### Runtimeについて
また、現在ランタイムでリフレクションを利用していますが、これをソースジェネレーターを利用し、改善することで速度を向上させたいと思っています。

### スクリプトノードの追加
会話の結果を後のゲームの挙動に使いたい場合など、独自のスクリプトを会話中に挟めるようにすることを検討しています。

### 画像の対応
今は画像との連携がしにくいですが、これを改善しGraph内で行えるようにしたいと考えています。
話しているキャラクターが強調表示されるなどです。

### アニメーションの追加
テキストのアニメーションもどんどん追加していきたいです。
また、利用者さんが独自にアニメーションを実装できるようにする予定です。

### リファクタリング
MagicTweenのTweenをまとめる機能を独自実装してしまいましたが、のちに調べるとちゃんとその機能が存在したため、そちらに修正を予定しています。

### 最適化
気づいた点があれば少しずつ最適化していこうと思っています。
Amazon GuardDutyとCloudTrail Insightsの違い

# Amazon GuardDutyとCloudTrail Insightsの違い

Amazon Web Services（AWS）は、高度なセキュリティ機能を提供し、クラウド上の資産を保護します。その中でも、Amazon GuardDutyとCloudTrail Insightsは、セキュリティと運用監視の強化に重要な役割を果たしますが、それぞれのサービスは異なる特徴と機能を持っています。この記事では、これら二つのサービスの基本的な違いとそれぞれの利点を、初心者にも分かりやすく解説します。

## Amazon GuardDutyの概要

### セキュリティ監視と脅威検出

#### 機能と特徴

Amazon GuardDutyは、AWS環境内の異常な活動や潜在的な脅威を識別するフルマネージドな脅威検出サービスです。このサービスは、ネットワークトラフィック、AWS CloudTrailのイベントログ、DNSログなどを分析し、機械学習と異常検出アルゴリズムを使用して不審な行動を検出します。

#### セキュリティの強化

GuardDutyは、不正アクセス、データ漏洩、その他のセキュリティリスクをリアルタイムで特定することで、クラウド環境のセキュリティを強化します。これにより、迅速な対応と脅威の軽減が可能になります。

## CloudTrail Insightsの概要

### 運用監視とアクティビティ分析

#### 機能と特徴

CloudTrail Insightsは、AWSアカウント内のAPI使用状況に関する洞察を提供するサービスです。この機能は、AWS CloudTrailの一部として利用可能で、APIコールの異常なパターンや急激な変更を自動的に検出します。

#### 運用効率の向上

CloudTrail Insightsは、アカウントの使用状況を監視し、通常とは異なる行動や潜在的な設定ミスを特定することで、運用効率を向上させます。この情報は、リソースの最適化や問題解決のプロセスに役立ちます。

## GuardDutyとCloudTrail Insightsの違い

### 目的と焦点の違い

Amazon GuardDutyは主にセキュリティ脅威の検出に焦点を当てているのに対し、CloudTrail InsightsはAWSアカウント内の運用活動とAPI使用状況の分析に重点を置いています。つまり、GuardDutyはセキュリティリスクの識別と軽減に特化し、CloudTrail Insightsは運用の異常や効率性の向上に貢献します。

### 使用方法と結果

GuardDutyは、機械学習と既知の脅威シグネチャを使用してセキュリティ脅威を識別します。一方、CloudTrail Insightsは、アカウント内のAPI活動における異常なパターンを検出することで、運用上の問題を明らかにします。

## まとめ

Amazon GuardDutyとCloudTrail Insightsは、AWS環境のセキュリティと運用効

率を高めるための強力なツールですが、それぞれ異なる目的と機能を持っています。GuardDutyは脅威検出に特化しており、CloudTrail Insightsは運用監視に焦点を当てています。AWSを利用する際には、これらのサービスを適切に選択し、組み合わせることで、セキュリティと効率性を最大限に高めることができます。
[object object]の対処法（javascrpit）

 jsonをコンソールログに出力しようとすると[object object]と表示される

 これは、JSONがJavaScript のオブジェクトと認識されているから。
 JSON文字列に変換する。

### 対処法①
JSON.stringify

~~~javascript:例
json="{省略}";
console.log("結果:"+JSON.stringify(json));
~~~~

しかしこれだとなぜか、改行されずに表示される
すごく見ずらい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2780454/3d466a88-346b-e053-fdff-232f96a4541d.png)

### 対処法②
なぜかわからないが、console.logの()内を変数だけしか書かなかったら、オブジェクトにならない。

~~~javascript:例
json="{省略}";
console.log(json);
~~~~

こっちだときれいに表示される。
めちゃ見やすくなるため、こっちの方法をお勧めする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2780454/8c96c6c3-f97e-f1e1-3aa1-e6c362cf6b02.png)
形式記述言語VDM++の制御構文（return文）をJava C# Re:Mind(自作言語)と比較

# はじめに

要求仕様記述段階での使用が主に想定されている数学的形式手法VDM(Vienna Development Method)[^1]のオブジェクト指向拡張言語VDM++ですが、ロジックの実装も記述できる構文が用意されています。本記事ではVDM++の制御構文（return文）をJavaとC#そして自作言語のRe:Mind[^2] と比較してみます。

## この記事内容の作業目的
VDM++の下記の制御構文[^3][^4]についていくつかの記事に分割して比較検討します。クラスの定義構文についてはこちらの記事[^5]を参照することができます。

・ブロック文
・コメント文
・代入文
・条件文
・ループ文
・call文
・**return文**　←本記事対象
・例外

VDM++はオブジェクト指向言語的な言語要素を持ち、数学的形式手法言語の中では一般のプログラミング言語のオブジェクト指向言語に近い面があります。

Re:MindはJavaやC#の経験者向けに設計された日本語プログラミング言語の一種で、ロジック仕様記述言語とトランスコンパイラ言語とで言語仕様を共有しています。

VDMのような数学的形式手法を使わない場合は、一般的に自然言語の日本語で要求仕様が記述されているものと推察されます。本記事では数学的形式手法と自然言語の日本語記述とのはざまで、構造化された日本語が要求仕様記述に使えないか模索しています。

ロジック仕様記述言語は疑似言語みたいなものですから、コンパイラを通さないことを前提にするならば未定義の関数を要件表記として使うこともできます。自然言語の日本語で記述するよりは厳密な構造的な記述が可能です。

## この記事内容の保証
各言語で書かれた引用ソースの妥当性は保証されません。また、本記事に開示された自作言語の仕様は、開発中の仕様のため予告なく変更される場合があります。

# 構文比較
## VDM++
```vdm:VDM++
    doAnything: () ==> int
    doAnything() ==
    (
       --todo1
       return i;
    )
```
```vdm:VDM++
    doAnything: () ==> ()
    doAnything() ==
    (
       --todo1
       return
    );
```
VDM++のreturn文は操作定義ブロック文内の式の値を戻します。変数や値を返さない場合はその時点でブロック文の実行を終了します。
VDM++のブロック文は()で囲われた範囲となります。セミコロンによる構文の終端ですが、ブロック文の末尾の行の終端は省略可能（下段のようなイメージ。上段のようにつけてもツールによってはエラーとならない）。定義ブロック文の終端にも下段イメージのように終端は必要。
## Java
```java:Java
    int doAnything()
    {
       int i = 1;
       //todo1
       return i;
    }
```
```java:Java
    void doAnything()
    {
       //todo1
       return;
    }
```
Javaのreturn文は関数定義ブロック文内の式の値を戻します。変数や値を返さない場合はその時点でブロック文の実行を終了します。
Javaのブロック文は{}で囲われた範囲となります。
## C#
```cs:C#
    int doAnything()
    {
       int i = 1;
       //todo1
       return i;
    }
```
```cs:C#
    void doAnything()
    {
       //todo1
       return;
    }
```
C#のreturn文は関数定義ブロック文内の式の値を戻します。変数や値を返さない場合はその時点でブロック文の実行を終了します。
C#のブロック文は{}で囲われた範囲となります。
## Re:Mind

```mind:Re:Mind
    ▽int doAnything()
        ・int i = 1
        //todo1
        □返す i
    △
```
```mind:Re:Mind
    ▽void doAnything()
        //todo1
        □返す
    △
```
Re:Mindの返す文は関数定義ブロック文内の式の値を戻します。変数や値を返さない場合はその時点でブロック文の実行を終了します。
Re:Mindのブロック文は▽の定義行の末尾から△で囲われた範囲となります

# おわりに
いかがでしたでしょうか？VDM++にもreturn文があるのですね。アルゴリズムの陰定義のイメージが強いVDM++ですが、普通にロジックは組めそうですね。
VDM++でロジックまで書いた場合、実装用のプログラミング言語のソースコードにどのように反映させるかが問題です。



[^1]: IBMのウィーン研究所で1960年代から70年代にかけて開発された形式手法。その実装には1996年にISO標準（ISO_IEC_13817-1）となったVDM-SLと、そのオブジェクト指向拡張のVDM++がある。
[^2]: Qiita [オープンな設計言語仕様 日本語ロジック仕様記述言語 Re:Mind（リマインド）](https://qiita.com/mylifewithviolin/items/52f806777e6ea031de94) 参照
[^3]: FMVDM　[VDMTools 付属文書](http://fmvdm.org/doc/index-ja.h
[^4]: FMVDM-> github [[PDF] VDMTools VDM 言語マニュアル VDM++](https://github.com/vdmtools/vdmtools/raw/stable/doc-jp/lang-man/langmanpp_a4J.pdf)
[^5]: Qiita [要求仕様 形式記述言語VDM++ との構文比較 ロジック仕様記述言語 Re:Mind（リマインド）](https://qiita.com/mylifewithviolin/items/2a8c6dc66cead04536a8)
オブジェクト指向とは

オブジェクト指向とは設計手法の事。
４大原則というべきものがある。

# １：カプセル化
この処理は何か、この処理をしている所はどこか、見てすぐに内容を把握できるようにする、把握しやすくする為に、同様の処理のデータと処理をまとめるという考え方。

# ２：データ隠蔽
カプセル化を維持する為の考え方。具体的な実装で言うとprivateにすると言うこと。

# ３：抽象化
個々のオブジェクトをそれぞれ作ると煩雑になってしまう。
そこで、個々のオブジェクトの本質を突き詰めて簡単にする事を抽象化という。
抽象化した物を利用して個々のオブジェクトを作り、抽象化した物を介して個々のオブジェクトにアクセスする事をポリモーフィズム（多様化）という。

# ４：情報隠蔽
何から何までpublicにしている（こうする人が非常に多いが）と、そのシステムについて何も知らない新人さんが保守としてプロジェクトに入って来た場合、本来非公開にしたい別クラスのコードを再利用して開発してしまい、それが積み重なるととんでもなくスパゲッティなコードになってしまう危険性がある。
そういう事を防ぐ為にコードの公開・非公開をしっかり分けましょうという考え方。
具体的に言うと、パッケージ分けを設計し、アクセス修飾子はデフォルト（無し。同じパッケージからのみアクセス可）にする。
外部から利用したい場合はインターフェースのみpublicにして（抽象化）し、そのインターフェースにcreateメソッドを用意してそのメソッドを介してのみimplインスタンス生成を行えるようにする。
AR(2)モデル

## AR(2)モデルの基本

AR(2)モデルは以下のように表される。

$$
X_t = \phi_1 X_{t-1} + \phi_2 X_{t-2} + \epsilon_t
$$

ここで、$X_t$は時刻$t$での時系列の値、$\phi_i$は自己回帰係数、$\epsilon_t$は平均がゼ$0$で分散が $\sigma^2$ のホワイトノイズ誤差である。

$X_t$という表記法が一般的であるが、人によっては$X(t)$と書いた方がピンとくるかもしれない。



## 定常性の条件

AR(2)モデルが定常であることは、特性方程式$t^2 - \phi_1 t  - \phi_2 =0$のすべての解の絶対値が$1$より小さいことと同値である。




## ユール・ウォーカー方程式
期待値0のAR(p)において自己相関係数とモデルの係数の関係を表した式。以下の$p=2$の場合がよく文献では紹介されている。

時系列モデルでは
$$\gamma_t=Cov[X_0,X_{t}], \enspace \gamma_{|t-s|}=Cov[X_t,X_{s}]$$という様に表し、自己共分散関数と呼ぶことが一般的である。
また、
$$\rho_k=\frac{\gamma_k}{\gamma_0}$$をラグ$k$の自己相関関数と呼ぶ。
このとき、$p=2$の場合のユール・ウォーカー方程式は以下のようになる。

```math:
\begin{pmatrix} \phi _{1} \\ \phi _{2}\end{pmatrix}=\begin{pmatrix} 1 & \rho _{1} \\ \rho _{1} & 1 \end{pmatrix}^{-1}\begin{pmatrix} \rho _{1} \\ \rho _{2} \end{pmatrix}
```

## AR(2)モデルのコードの例

```python:
import numpy as np
import statsmodels.api as sm
import japanize_matplotlib
import matplotlib.pyplot as plt

# AR(2)モデルのパラメータ。
phi1 = 0.5
phi2 = -0.2
np.random.seed(42)

# 時系列データ生成。
n = 100  # データ点の数。
ar2_data = [0, 0]  # 最初の2つの点は初期値として0を設定。
for i in range(2, n):
    # AR(2)モデルの式に従ってデータ生成。
    x = phi1 * ar2_data[i-1] + phi2 * ar2_data[i-2] + np.random.normal(scale=0.5)
    ar2_data.append(x)

# 時系列データを可視化。
plt.plot(ar2_data)
plt.title('AR(2)モデルの時系列データ')
plt.xlabel('時間')
plt.ylabel('値')
plt.show()

# AR(2)モデルのフィッティング
model = sm.tsa.AR(ar2_data)
result = model.fit(maxlag=2)  # AR(2)モデルなので、maxlagは2
print(result.summary())
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359600/e7b1c839-5329-9b21-e391-72ba49b6b225.png)

## 線形・ガウス型状態空間モデル

上述の式は以下の様に書くことができる。
```math
\begin{bmatrix} X_{t+1} \\ X_{t} \end{bmatrix}=\begin{bmatrix} \phi _{1} & \phi _{2} \\ 1 & 0 \end{bmatrix}\begin{bmatrix} X_{t} \\ X_{t-1} \end{bmatrix}+\begin{bmatrix} 1 \\ 0 \end{bmatrix}\varepsilon _{t}
```
よって

```math
Z_t=\begin{bmatrix} X_{t} \\ X_{t - 1} \end{bmatrix}, ~F=\begin{bmatrix} \phi _{1} & \phi _{2} \\ 1 & 0 \end{bmatrix},~G=\begin{bmatrix} 1 \\ 0 \end{bmatrix}
```
とおけば

$$Z_t=FZ_{t-1}+G\varepsilon _{t}$$

と表すことができる。これは線形・ガウス型状態空間モデルのシステムモデルの特別な場合の式である。
また、
```math
X_{t}=\begin{bmatrix} 1 & 0 \end{bmatrix}\begin{bmatrix} X_{t} \\ X_{t-1} \end{bmatrix}+0
```
という自明な式は、線形・ガウス状態空間モデルの観測モデルの特別な場合となっており、この2つの式から、AR(2)モデルは線形・ガウス状態空間モデルの特別な場合であることがわかる。

通常、AR(2)モデルのパラメータ推定には頻度主義的手法が一般的に使われるが、状態空間モデルの一例としてAR(2)モデルを考え、その状態空間モデルにベイズ統計学の手法を適用することも可能である。
形式記述言語VDM++の制御構文（cases文）をJava C# Re:Mindの（switch文）と比較

# はじめに

要求仕様記述段階での使用が主に想定されている数学的形式手法VDM(Vienna Development Method)[^1]のオブジェクト指向拡張言語VDM++ですが、ロジックの実装も記述できる構文が用意されています。本記事ではVDM++の制御構文（cases文）をJavaとC#そして自作言語のRe:Mind[^2] （switch文）と比較してみます。

## この記事内容の作業目的
VDM++の下記の制御構文[^3][^4]についていくつかの記事に分割して比較検討します。

・ブロック文
・代入文
・**条件文**　←本記事対象
・ループ文
・call文
・return文
・コメント文
・例外

VDM++はオブジェクト指向言語的な言語要素を持ち、数学的形式手法言語の中では一般のプログラミング言語のオブジェクト指向言語に近い面がありますが、かなり別物という面もあります。また、VDMのような数学的形式手法を使わない場合は、一般的に自然言語の日本語で要求仕様が記述されているものと推察されます。本記事では数学的形式手法と自然言語の日本語記述とのはざまで、構造化された日本語が要求仕様記述に使えないか模索しています。

クラスの定義構文についてはこちらの記事[^5]を参照することができます。

## この記事内容の保証
※この記事には実装的な情報が含まれます。各言語で書かれた引用ソースの妥当性は保証されません。また、本記事に開示された自作言語の仕様は、開発中の仕様のため予告なく変更される場合があります。

# 構文比較
## VDM++
```vdm:VDM++
    cases val:
        const1 -> (
            //todo1
        ),
        const2 -> (
            //todo2
        ),
        others -> (
             //todo3
        )
    end
```
VDM++のcases文はプログラミング言語のswitch文と大枠の構造は似ていますが、分岐先の選択肢には予約語的なトークン（switchに対するcase句のようなもの）はなく、選択肢の値からアロー演算子で選択先が記述されるというのが特徴的です。
```vdm:VDM++
    cases val:
        const11, const12 -> (
            //todo1
        ),
        const21, const21 -> (
            //todo2
        ),
        others -> (
             //todo3
        )
    end
```
分岐先の選択肢には値を列挙して、複数条件に合致させることができます。

## Java
```java:Java
    switch(val){
        case const1:
            //todo1
            break;
        case const2:
            //todo2
            break;
        default:
            //todo3
            break;
    }
```
JavaはC/C++の構文を継承し、caseブロック内にbreakを書かないと次の合致するcase内に処理が移るフォールスルー動作ありの言語となります。
## C#
```cs:C#
    switch(val){
        case const1:
            //todo1
            break;
        case const2:
            //todo2
            break;
        default:
            //todo3
            break;
    }
```
C#はC/C++の構文を継承していますが、caseブロック内にbreakを書かないとエラーとなるフォールスルー動作なしの言語となります。
## Re:Mind
```mind:Re:Mind
        ◇値　で分岐する
        ◇定数1
            //todo1
            □脱出する
        ◇定数2
            //todo2
            □脱出する
        ◇既定
            //todo3
            □脱出する
        ◇ここまで
```
値は半角かっこ()で囲っても囲わなくても可です。
◇定数1　がCase文に相当する構文で、ここでは実行文を書く場合改行必須です。「◇既定」がdefalut文相当です。
□脱出するがbreak文に相当します。

Re:MindはJavaやC#の経験者向けに設計された日本語プログラミング言語の一種で、ロジック仕様記述言語とトランスコンパイラ言語とで言語仕様を共有しています。自然言語の日本語で記述するよりは厳密な構造的な記述が可能です。どちらかというと箇条書きを想定していて、箇条書きの冒頭記号□◇〇▽が制御トークンになっています。


# おわりに
いかがでしたでしょうか？VDM++のcases文にアロー演算子が記法として採用されているのが興味深いです。


[^1]: IBMのウィーン研究所で1960年代から70年代にかけて開発された形式手法。その実装には1996年にISO標準（ISO_IEC_13817-1）となったVDM-SLと、そのオブジェクト指向拡張のVDM++がある。
[^2]: Qiita [オープンな設計言語仕様 日本語ロジック仕様記述言語 Re:Mind（リマインド）](https://qiita.com/mylifewithviolin/items/52f806777e6ea031de94) 参照
[^3]: FMVDM　[VDMTools 付属文書](http://fmvdm.org/doc/index-ja.h
[^4]: FMVDM-> github [[PDF] VDMTools VDM 言語マニュアル VDM++](https://github.com/vdmtools/vdmtools/raw/stable/doc-jp/lang-man/langmanpp_a4J.pdf)
[^5]: Qiita [要求仕様 形式記述言語VDM++ との構文比較 ロジック仕様記述言語 Re:Mind（リマインド）](https://qiita.com/mylifewithviolin/items/2a8c6dc66cead04536a8)
railsにBootstrap導入後の表示が左寄り問題

# 左寄せになっているのを治す方法

Bootstrap導入直後の、
app>views>layouts>application.html.erb

```rails
<!DOCTYPE html>
<html>
  <head>
    <title>MyCloset</title>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
    <%= javascript_importmap_tags %>
  </head>

  <body>
    <%= yield %>
  </body>
</html>
```

この時　bodyに直接書き込まれているのが左寄せになる原因です。
（左寄せしたい人は直接記入が良いみたいです）

yieldをdivタグで囲み、Bootstrapがコンテンツを管理するcontainerに入れます。

```rails
<!DOCTYPE html>
<html>
  <head>
    <title>MyCloset</title>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
    <%= javascript_importmap_tags %>
  </head>

  <body>
    <div class="container">
    <%= yield %>
    </div>
  </body>
</html>

```


これで左寄せ問題は解決です🎵
wslでelixir その105

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
githubに、livebook、アップしてみた。

# 手順

# githubに、リポジトリ作る。

- https://github.com/にSign inする。
- 右上の「+」から「New repository」を選択する。
- 「Repository name」にリポジトリ名(ohi_Livebook)を入力する。
- Description にelixir livebook
- リポジトリを公開する場合は「Public」をチェックする。
- 「Initialize this repository with a README」をチェックする。
- license は、Mit
- 「Create repository」をクリックする。

# アクセストークンを作る。

- GitHubにログイン
- 右上の自分のアイコンをクリック
- 「Settings」をクリック
- 左メニュー下部の「Developer settings」をクリック
- 左メニューの「Personal access tokens」をクリック
- 右上の「Generate new token」をクリックしてアクセストークンを作成
- ※パスワードが聞かれたらgitのパスワードを入力する
- Note：任意の名称を入れてください。
- Expiration：何日の有効にするかを決めてください。（悩むなら30日でいいです）
- Select scopes：repo チェックを入れる
- 設定が終わったら「generate token」を押してアクセスコードを発行する。
- 作成したトークンをコピーする

# wslに、リポジトリ作る。

```
$ mkdir github

$ cd github

$ git init
Initialized empty Git repository in /home/ore/github/.git/

$ git clone https://github.com/ohisama/ohi_Livebook.git
Cloning into 'ohi_Livebook'...
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (4/4), 1.24 KiB | 40.00 KiB/s, done.

$ cd ohi_Livebook

```

# ファイルをコピーする。

```
$ explorer.exe .
```

# pushする。

パスワードに、アクセストークンを使う。

```
$ git config --global user.name "ohisama"

$ git config --global user.email ""

$ git add .

$ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   stage1/hello.livemd
        new file:   stage1/hello2.livemd
        new file:   stage1/map.livemd
        new file:   stage1/qiita.livemd
        new file:   stage1/ronri.livemd
        new file:   stage1/socket.livemd
        new file:   stage1/vega.livemd

$ git commit -m "update2"
[main ea576ce] update2
 7 files changed, 1627 insertions(+)
 create mode 100644 stage1/hello.livemd
 create mode 100644 stage1/hello2.livemd
 create mode 100644 stage1/map.livemd
 create mode 100644 stage1/qiita.livemd
 create mode 100644 stage1/ronri.livemd
 create mode 100644 stage1/socket.livemd
 create mode 100644 stage1/vega.livemd

$ git push
Username for 'https://github.com': ohisama
Password for 'https://':
Enumerating objects: 11, done.
Counting objects: 100% (11/11), done.
Delta compression using up to 4 threads
Compressing objects: 100% (10/10), done.
Writing objects: 100% (10/10), 10.17 KiB | 1.02 MiB/s, done.
Total 10 (delta 0), reused 0 (delta 0)
To https://github.com/ohisama/ohi_Livebook.git
   57e4c10..ea576ce  main -> main

```

# 成果物

https://github.com/ohisama/ohi_Livebook

以上。
はじめてのQiitaと電子工作#0

# はじめに
当記事はRaspberry Pi zero WHの起動テストの忘備録 兼 日記です。

:::note alert
警告
この記事は、あくまで個人のメモのようなものであり、参考にする際は自己責任でお願いします。
:::
## やること
Raspberry Pi zero WH、以降ラズパイを使って
電子工作するための初期設定と起動までやります。

[](#)
# 目次
[はじめての電子工作](#はじめての電子工作)
┗[購入したもの](#購入したもの)

[はじまり](#はじまり)
┗[OSのインストール](#osのインストール)

[感想](#感想)

[最後に](#最後に)


## はじめての電子工作

### 購入したもの

Raspberry Pi zero WH
<img width="200px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616680/63e90fc2-bcb4-04b8-5a66-690d36c91da9.jpeg">
思ってたより小さい!手のひらサイズです。

## はじまり
### OSのインストール
<img width="200px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616680/37277f7e-9fe2-1933-2a3b-368492efa8a4.png">

ラズパイを動かすには、
まず↓の公式サイトからRaspberry Pi Imager[^4]というソフトをが必要です。

https://www.raspberrypi.com/software/

<img width="600px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616680/8e8674e8-562a-908d-adeb-576123500027.png">
<br>
私が使用しているOSはWindowsなのでWindows用のImagerをダウンロードします。

PCにmicroSDカードをセットし、「Raspberry Pi Imager」を起動します。
<img width="500px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616680/e26869a8-57ae-718a-66d9-5db884c8a0b5.png">

デバイスをRaspberry Pi zeroに
OSをRaspberry Pi OS (Legacy)に
ストレージは先ほど入れたSDカードを選択して
「次へ」を押すと設定画面へ遷移します。
<img width="500px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616680/5a41c342-2278-9a56-4b14-83bd08f0d406.png">
ユーザー名、パスワード、Wi-Fiとタイムゾーンを設定します。

保存を押すと書き込みが開始されました。

<!--書き込みボタンが表示されたとき-->
<img width="500px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616680/f88d2bc1-3a47-1422-fbfb-5ff988d6a553.png">


書き込み完了後
<img width="500px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616680/f13f3d4c-28ac-c0f2-4e2e-7b85426a2143.png">

PCからmicroSDカードを取り出します。
書き込みには２分ほど掛かりました。

### 準備段階

さきほどRaspberry Pi OSを書き込んだmicroSDカードをラズパイにセットします。
<!--セットした画像-->
<img width="500px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616680/51ca31a6-79d6-f1a1-0626-0c0379e1e845.jpeg">

キーボード、マウス、モニターをラズパイに接続してOSの設定をします。

:::note warn
ラズベリーパイは電源ケーブルを挿した瞬間に起動して、microSDカード内のOSを読込み始めてしまうのでACアダプターは最後に接続しましょう。
:::

### ラズパイOSの初期設定
Boot!!!
<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616680/1d8017ce-16f1-45af-c8a4-cc77b796d0d3.jpeg">
<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616680/9e759c98-4d5c-bad8-4e12-a81ec398b185.jpeg">
<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616680/bc874f4d-57a5-4cc2-65d3-049efbae91b5.jpeg">
無事起動できました！

## 最後に
読んでくれてありがとうございます。
初めて記事を書くので下手ですが頑張ります！
次はLチカをしてみたいと考えています。

[^4]: Raspberry Pi Imagerは、ラズパイで使うOSのダウンロードとmicroSDの書き込みを一度に行ってくれるソフトウェアです。
Chrome のパスワードマネージャーが組織に無効されました

組織のポリシーによって禁止された ```Chrome``` の機能は、Windows Registry を変更することで回避可能です。今の時代、パスワードマネージャー使わせてもらえないと、生きていけない！

### PasswordManagerEnabled (パスワードマネージャー有効化)
https://chromeenterprise.google/policies/?policy=PasswordManagerEnabled

```
Software\Policies\Google\Chrome\PasswordManagerEnabled
```

### SyncTypesListDisabled (同期禁止項目の解除)
https://chromeenterprise.google/policies/#SyncTypesListDisabled

```
Software\Policies\Google\Chrome\SyncTypesListDisabled
```
ロボカップ最後の振り返り

去年のロボカップの振り返りを途中で放置していたことを思い出したので供養しておきます。

# ロボカップが終わったよ
RCJJ2023 Japan Openのレスキューラインに参加しました。形ある結果が残せたのでそこそこ満足です。
高校でのロボコン生活全体を振り返ってみます。
技術的な話はまたどこかで。

# 効率よく技術を高めるには
＿人人人人人人人人人人人人人人＿
＞ 他のチームを研究しよう！！ ＜
￣Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y￣
とにかく1にも2にも**他のチームを研究する**のが1番です。
これをするだけで、今まで思いつかなかったアイデアがたくさん入ってきます。

ロボカップの精神に
> ロボカップの世界競技会の精神は、どのような技術開発やカリキュラム開発成果も、競技終了後、他の参加者に共有されるべきということである。こうした情報の共有は、教育構想としてのロボカップジュニアの使命をさらに推し進めるものである。

とあるように他のチームを研究することは公式が推奨していることです。※丸パクリはだめだよ

例えば、[ホームページ](https://www.robocupjunior.jp/index.html)には過去の全国大会出場チームのポスターやドキュメントが公開されています。それだけでなくX~~Twitter~~などで先人たちが自分の技術を発信していたりします。それらを最大限吸収することが進化する最短ルートだと考えています。

# お金の話
大会には様々な種類のロボットが出場しています。それと同時に「金かかってんなー」と思うチームもたくさんあります。
ロボカップにおいて、資金が潤沢であるか否かがチームの強さに影響するか。これは人によってかなり意見が違ってくる話だと思います。

私個人の意見として、資金と強さの関係を一切否定することはできません。
資金が潤沢でなくても強いロボットを作れるのは事実でしょう。ですが、資金が潤沢でより優れた部品を扱えるチームがで有利になる面がることもまた事実だと思います。

そもそも、ロボカップのレスキューラインで多く使わてれいるEV3やSPIKE Primeでさえも5万円を優に超える高級品なのです。WROのように部品をLEGOに限定すればよいとも言い切れません。他のロボットキットも1万円を超えるものが多いです。個人で参加するのに敷居が高いのは事実だと思います。~~サッカーとメイズは次元が違うので知りません~~

早い話何が言いたいかというと、なにかロボコン系のことをしたいのなら、ロボコンに出ている学校に進学するのが1番安上がりな気がします。あとは予算をめぐって生徒会ないし先生ないしとバトりましょう。~~生徒会を兼ねている人が身内にいると予算の話で何かと融通が利くよ~~
ロボット教室は...通ったことがないので何とも言えません。

# チーム競技でなかった
先に言っておくとこれは誰が悪いといった話ではないです。
私にもチームメイトがいたわけですが、実際には私が1人でハードからソフト、ポスターまでほぼすべてのことをしていました。
そうなってしまった原因は大会に対する温度差なのかなと思っています。

はじめは技術的なレベルに大きな差はありませんでした。しかし熱量の差によって知識的、技術的なギャップがだんだん生まれてきます。
ここでチームマネジメント能力がある人はそのギャップを埋めようとするのでしょうが、当時の私にはできませんでした。そしてギャップだけが広がり続け、お互い歩調を合わせることを諦めてしまった結果、ソロプレイなチームになってしまいました。結局は私が独善的すぎたということです。

似たような現象は後輩のチームでも見られました。
では、こうした現象を防ぐためにはどうすべきだったのか、4つの選択肢が合ったと思います。
* そもそも同じくらいの熱量を持った人(もしくは頭のいい人)とチームを組む。
    これができれば苦労はしないという話ですね。私の実体験でも優秀な人達と組んだときには様々なことを協力して進めることができたので、チームメイトを見極めるのも1つの選択肢かもしれません。 

* チームメイトにも同じくらいの熱量を持ってもらう。
    これに関しては、私もそうやってすればいいのかわかりません。ですが、スタートで差があっても努力次第ですぐに埋まるので、すでに差が開いてしまっていても有効だと思います。 

* 情報・知識の共有を徹底して歩調を合わせる。
    上のことが若干、前提条件になってきますが、これ以上のギャップを作らないためにもお互いのやっていることを理解するのは大切だと思います。  

* 熱量の差があることは前提で、できる限り協力する。
    あまりにもアバウトですが、最も現実的なのはこれかなと思います。 

こういった問題は「チーム 温度差」あたりで検索すれば「共通認識を持つ」とか「信頼関係を...」とか色んな意見が出てきます。もし同じような悩みがある方はそちらを参考にしてみるといいかもしれません。

↓メイズで優勝した方のブログが参考になると思います。

https://blog.shirokuma89.dev/20230401/

# さいごに
この大会をもって、私が高校の部活で出る大会はすべて終了しました。これからは大学受験です。少なくとも今後1年以上はロボットに触れることができなくなります。

私が今通っている高校に進学した理由の一つが、コンピューター部でロボットを作っているのが楽しそうだった、ということでした。中学の頃の自分に「〇〇高校(私が通っている高校)に行きな」って背中を押せるぐらいに、楽しく貴重な経験をすることができたと思います。顧問やチームメイト、先輩、後輩に感謝です。

大学生になってからもロボカップないしロボコンないし、なにかそういった活動はしていきたいと思っています。なんなら社会人になってもやっていきたいですね笑。それぐらい楽しかったです。

# P.S.
これを書いたのが23年の4月ごろ、もう11月の末になってしまいました。
大学はRCJJとWRO、課題研究の実績を全面に押し出してなんとか合格をつかむことができました。共テの勉強にも身が入りづらいビミョーな時間を過ごしております。

RCJJはエントリーの締め切りが合格発表よりも早かったので参加できませんでした。🥺
ローカルな○○オープン系の大会にはまだ参加できるはずなのでそこに向けて最後の1台を作っていこうと思います。
Ansibleでできることと課題

# Ansibleでできることと課題

Ansibleは、現代のIT環境における自動化の要求に応えるための強力なツールです。その汎用性と拡張性は、多くの組織で高く評価されていますが、同時に特有の課題やセキュリティの懸念も存在します。この記事では、Ansibleが提供する多様な自動化機能と、それに伴う主要な課題について深く掘り下げていきます。

## Ansibleによる自動化の幅広い可能性

### サーバーとアプリケーションの構成管理
Ansibleは、サーバー設定の自動化、ソフトウェアのインストール、サービスの起動や停止など、日常的な構成管理タスクを簡素化します。これにより、一貫性と再現性のある環境を保証します。

### アプリケーションのデプロイメント
Ansibleの自動化ツールは、アプリケーションのデプロイメントプロセスを高速化し、手作業によるミスを減らします。これにより、リリースサイクルが加速し、ビジネスの柔軟性が向上します。

### ネットワークオートメーション
ネットワーク設定の自動化は、ネットワークポリシーの迅速な展開や変更を可能にし、全体的なネットワーク管理の効率を向上させます。

### クラウドプロビジョニング
クラウド環境におけるリソースのセットアップと管理を自動化することで、インフラストラクチャの柔軟性とスケーラビリティが向上します。

### セキュリティとコンプライアンス
自動化されたセキュリティポリシーの適用と監査プロセスにより、企業のセキュリティ基準とコンプライアンス要件を維持します。

## Ansibleの使用における課題とセキュリティ上の懸念
Ansibleに関連するデメリットや課題には、以下のような具体的な原因があります。

1. **スケーラビリティの制限**
   - 原因: Ansibleはエージェントレスであり、大量のノードに対する操作はネットワークオーバーヘッドや接続の問題を引き起こすことがあります。特に、並列性の制限やネットワーク帯域の制約がスケーラビリティに影響を与えることがあります。

2. **エラーハンドリングの複雑さ**
   - 原因: 複雑なプレイブックやロールの中でエラーが発生した場合、特定のタスクが失敗した正確な原因を特定するのが難しいことがあります。また、Ansibleのエラーメッセージが常に明確でない場合があり、デバッグが困難になることがあります。

3. **詳細な状態管理の欠如**
   - 原因: Ansibleは「アイドンポテンシー」原則に基づいて設計されていますが、他のツールのようにシステム全体の状態を継続的に管理する能力は限られています。これは、エージェントレスモデルの結果であり、状態の変更がプレイブックの実行時にのみ評価されるためです。

4. **学習曲線**
   - 原因: AnsibleのYAML構文は初心者には直感的でない場合があります。また、プレイブック、ロール、インベントリファイルなどの概念を理解する必要があり、これらの要素の相互作用を把握するのに時間がかかることがあります。

5. **セキュリティ上の懸念**
   - 原因: Ansibleは管理対象のサーバーに対して広範な権限を必要とするため、認証情報のセキュリティが重要です。不適切に管理されたSSHキーまたは資格情報は、セキュリティの脆弱性を引き起こす可能性があります。

6. **パフォーマンスの問題**
   - 原因: AnsibleはPythonで書かれており、特に大規模な環境や複雑なタスクではパフォーマンスの問題が発生することがあります。これは、特に大量のノードを同時に操作する際に顕著です。

これらの課題に対応するためには、Ansibleの使用方法を適切に計画し、セキュリティとパフォーマンスの最適化に注意を払うことが重要です。また、Ansibleの限界を理解し、必要に応じて他のツールや方法と組み合わせることが有効なアプローチとなります。

## k8sとの組み合わせ
Kubernetes（K8s）とAnsibleは、ITインフラストラクチャとアプリケーションの管理・自動化において異なるが補完的な役割を果たします。以下にその関連性について説明します。

### Kubernetes (K8s)

- **コンテナオーケストレーション**: Kubernetesはコンテナ化されたアプリケーションのデプロイメント、スケーリング、管理を自動化するためのシステムです。コンテナのライフサイクル管理、サービスディスカバリー、ロードバランシング、自己修復などの機能を提供します。

- **マイクロサービスアーキテクチャ**: Kubernetesはマイクロサービスベースのアプリケーションをサポートし、これらのサービス間の相互作用と管理を容易にします。

### KubernetesとAnsibleの組み合わせ

1. **Kubernetesクラスターのプロビジョニング**: AnsibleはKubernetesクラスターのセットアップとプロビジョニングを自動化するために使用できます。これには、必要なネットワーキングコンポーネント、ストレージ設定、ノードの構成などが含まれます。

2. **アプリケーションのデプロイメント**: AnsibleはKubernetes上で動作するアプリケーションのデプロイメントプロセスを自動化するために使われます。これには、コンテナイメージのビルド、Kubernetesマニフェストファイルの適用、サービスの設定などが含まれます。

3. **環境の管理**: Kubernetesクラスター内でのリソース（ポッド、サービス、ボリュームなど）の管理や、複数のクラスター環境の管理にAnsibleを使用できます。

4. **CI/CDパイプラインの統合**: AnsibleはCI/CDパイプライン内でKubernetesと連携し、アプリケーションのビルド、テスト、デプロイメントを自動化する一環として使用されます。

5. **カスタムリソースの管理**: Ansibleを使用してKubernetesのカスタムリソースを管理し、より複雑な操作を自動化することができます。

AnsibleとKubernetesはそれぞれ異なる役割を持ちながらも、コンテナ化されたアプリケーションのデプロイメントと管理において互いを補完する関係にあります。Ansibleは構成管理と自動化に優れており、Kubernetesはコンテナオーケストレーションとマイクロサービスの管理に特化しています。これらを組み合わせることで、より効率的で柔軟なインフラストラクチャとアプリケーションの管理が可能になります。

## 結論
Ansibleは、その自動化能力により多くの組織にとって価値のあるツールですが、スケーラビリティ、エラーハンドリング、セキュリティ、パフォーマンスの面での課題が存在します。これらの課題に対処するためには、適切な設計、計画、セキュリティ対策を施し、状況に応じて他のツールやアプローチと組み合わせることが重要です。これにより、Ansibleのポテンシャルを最大限に活用し、効率的かつ安全な運用を実現することができます。
ファイルマネージャー「ranger」で画像プレビューが表示されない問題の解決策


# 簡単に結論から

画像プレビュー用パッケージとターミナルエディタの**互換性がない**可能性があります。

そのため、ターミナルまたはパッケージを互換性があるモノへ変更することで解消します。例えばわたしが使用しているターミナルのAlacrittyでは、[ueberzugpp](https://github.com/jstkdng/ueberzugpp)パッケージが対応していたため、そちらに変更することで表示されるようになりました。

パッケージの例や、その設定方法はGithub上のWikiにある[Image Previews](https://github.com/ranger/ranger/wiki/Image-Previews#with-w3mimgdisplay)から確認できます。

# はじめに

この記事は、VIライクなコンソールファイルマネージャーである[ranger](https://github.com/ranger/ranger)で画像プレビューが表示されない問題の解決策を紹介します。

## 環境

- Alacritty: Version 0.12.3
- ranger: ranger 1.9.3

# 不具合の内容

`.config/ranger/rc.conf`ファイルを編集し、以下の行を追加します。

```plaintext:~/.config/ranger/rc.conf
set preview_images true
```

画像の描画機能付きのw3mをインストールします。今回わたしはArch Linuxを使用しているため、`w3m`パッケージを`pacman`コマンドでインストールしました。

```bash
$ sudo pacman -S w3m
```

rangerを再起動し、あらかじめ保存しておいた画像ファイルまで移動するも、画像プレビューが表示されませんでした。

rangerを閉じると、ターミナル上に以下のようなメッセージが表示されていました。

```bash
$ ranger
xdg-open: unexpected option '--'
Try 'xdg-open --help' for more information.
```

# 不具合の原因

画像プレビューが表示されない原因は、インストールしたw3mパッケージがターミナルエミュレーターのAlacrittyに対応していないためでした。

以下は、[Image Previews](https://github.com/ranger/ranger/wiki/Image-Previews)からの引用です。

> Get a compatible terminal. Terminals that are known to work are rxvt-unicode, xterm and st (at least since st 0.6, besides if it doesn't work under st, you maybe use ueberzug).

w3mパッケージはxtermなどのターミナルと互換性があるそうなのですが、今回わたしが使用しているAlacrittyとは互換性がなかったようです。

# 解決策

互換性がなかったということで、ターミナルエミュレータかパッケージのどちらかを変更することで、画像プレビューが表示されるようになります。

今回は`ueberzugpp`パッケージに変更することで対応しました。
このパッケージはArch Linuxの場合、[AUR](https://aur.archlinux.org/packages/ueberzugpp)からインストールできます。

パッケージをインストール後、`~/.config/ranger/rc.conf`ファイルを以下のように編集します。

```plaintext:~/.config/ranger/rc.conf
set preview_images true
set preview_images_method ueberzug
```

rangerを再起動後、画像ファイルまで移動することでプレビューが表示されるようになりました。

# 参考

https://www.reddit.com/r/bspwm/comments/c3o937/image_previews_in_ranger_using_alacritty/
Rubyについて回答

## 問題1-1の答え
```ruby:ruby_1.rb
puts "おはよう"
```


## 問題1-2の答え
```ruby:ruby_1.rb
puts 5
puts 9 + 9
puts 6 - 7
```

## 問題1-3の答え
```ruby:ruby_1.rb
puts 50 + 5
puts "66"
```

## 問題1-4の答え
```ruby:ruby_1.rb
puts 5 * 4
puts 8 / 4
puts 9 % 5
```

## 問題1-5の答え
```ruby:ruby_1.rb
puts "こんばんは！" + "Ruby"
```

## 問題2-1の答え

```ruby:ruby_2.rb
text = "おはよう"

puts text
```

## 問題2-2-1の答え

```ruby:ruby_2.rb
message = "Ruby"

puts message

text = "エンジニア"

puts message + text
```

## 問題2-2-2の答え
```ruby:ruby_2.rb
num1 = 3

puts num1

num2 = 5

puts num1 + num2
```

## 問題2-3の答え
```ruby:ruby_2.rb
num1 = 5
puts num1 

num1 =  3

num1 = num1 - 2

puts num1
```
## 問題2-4の答え
```ruby:ruby_2.rb
birthplace =  "仙台"

puts "私の出身は#{birthplace}です。"
```

## 問題3-1の答え
```ruby:ruby_3.rb
rain = 65
if rain > 60
 puts "傘を持っていきましょう"
end
```

## 問題3-2の答え
```ruby:ruby_3.rb
rain = 40
if rain > 60
 puts "傘を持っていきましょう"
elsif rain >= 40
 puts "傘を持って行った方がいいですね"
else
 puts "傘はいりません"  
end
```
## 問題3-3の答え
①

```ruby:ruby_3.rb
a = "山田"
if a == "山田"
 puts "私の名前は山田です。"
end
```

②

```ruby:ruby_3.rb
b = "山田"
if b != "小松"
  puts "私の名前は山田ではありません。"
end
```

## 問題4-1の答え

```ruby:ruby_4.rb
countries = ["日本","アメリカ","イタリア"]

puts countries
```

## 問題4-2の答え

```ruby:ruby_4.rb
countries = ["日本","アメリカ","イタリア"]

puts "私は#{countries[2]}出身です。"
```

## 問題4-3の答え
```ruby:ruby_4.rb
studys = ["国語","数学","体育"]

studys.each do|study|
 puts "私は#{study}が好きです"
end
```

## 問題5-1の答え
```ruby:ruby_5.rb
user = {"name" => "Kida","sex" => "Man"}

puts user
```

## 問題5-2の答え
```ruby:ruby_5.rb
user = {"name" => "Kida","age" => 29}

puts user

user["age"] = "二十九"

puts user
```

## 問題5-3の答え
```ruby:ruby_5.rb
user = {"name" => "Kida","age" => 29}

puts user

user["sex"] = "Man"

puts user
```

## 問題6-1の答え

```ruby:ruby_6.rb
user = {:name => "YAMADA", :age => 29}

puts user
```

## 問題6-2の答え

```ruby:ruby_6.rb
user = {:name => "YAMADA", :age => 29, :sex => "man"}

puts user[:sex]
```

## 問題6-3の答え
```ruby:ruby_6.rb
user = {name:"YAMADA", country:"JAPAN", age:29}

puts user[:country]
```

## 問題7-1の答え
```ruby:ruby_7.rb
example = {name:"YAMADA"}

if example[:pref]
 puts "私の名前は#{example[:name]}です。東京出身です。"
else
 puts "私の名前は#{example[:name]}です。神奈川出身です。"
end
```

## 問題8-1の答え
```ruby:ruby_8.rb
user = [{name:"YAMADA", age:29}, #インデックス[0]
        {name:"KIDA", age:35},   #インデックス[1]
        {name:"KUBO", age:19}    #インデックス[2]
       ]
puts user[2]
```



## 問題8-2の答え
```ruby:ruby_8.rb
user = [{name:"YAMADA", age:29}, #インデックス[0]
        {name:"KIDA", age:35},   #インデックス[1]
        {name:"KUBO", age:19}    #インデックス[2]
       ]
puts user[0][:name]
```

## 問題8-3の答え
```ruby:ruby_8.rb
users = [{name:"YAMADA", age:29},
         {name:"KIDA", age:35},
         {name:"KUBO", age:29}
        ]
users.each do |user|
  puts user
end
```
【Node.js】Node.jsのVersion管理

Node.jsのVersion管理ツールは色々あり、主なものは以下のもの。
 - [nvm (Node Version Manager)](https://github.com/nvm-sh/nvm)
   unix, macOSで動作可能。
   Windows版は[nvm-windows](https://github.com/coreybutler/nvm-windows/releases)
 - [fnm](https://github.com/Schniz/fnm)
   unix, macOS, windowsで動作可能。
   Rustで作られた高速管理ツール
 - [Volta](https://github.com/volta-cli/volta)
   unix, macOS, windowsで動作可能。
   Rustで作られた高速管理ツール
 - [n](https://github.com/tj/n)
   unix, macOS, windows WSLで動作可能。
   Windows版は無さそう。
   非常にシンプルな仕様

今回は、[Microsoft公式ページ](https://learn.microsoft.com/ja-jp/windows/dev-environment/javascript/nodejs-on-windows)でも紹介されており、Windowsでよく使われているnvm-windowsの使い方を紹介する。

## nvm-windows

https://github.com/coreybutler/nvm-windows

### インストール方法
1. 下記URLからnvm-setup.zipをダウンロードする
    https://github.com/coreybutler/nvm-windows/releases
1. 展開して、nvm-setup.exeを実行する

### 使い方
1. nvmのversion確認
    ```nvm version```
1. インストール可能なNode.js Versionの確認
    ```nvm ls available```
1. 特定のVersionのNode.jsのインストール
    ```nvm install 18.18.1```
1. LTSで最新のVersionのNode.jsのインストール
    ```nvm install lts```
1. 特定のVersionのNode.jsのアンインストール
    ```nvm uninstall 18.18.1```
1. インストールされているNode.jsのVersionを確認
    ```nvm ls```
1. 特定のNode.js Versionに切り替える
    ```nvm use 20.9.0```

### まとめ
今回は、WindowsにおけるNode.jsのVersion管理ツールについて紹介した。
PostgreSQLにおけるビュー、マテリアライズドビューについて

# ビューとは？

一言で言うと、「仮想テーブル」です。
指定のSELECT文の結果を、あたかもテーブルかのように扱うことができる仕組みです。

### ビューの利点
複雑なSELECT文を都度書かずに済みます。

### ビューの欠点
 処理速度が遅いことです。
ビューは実体としてのデータを持たないため、
上記クエリを実行するたびに、
ビューに定義されたSELECT文に置き換えられて実行されることになります。

### ビューの作成構文

```sql
CREATE VIEW ビュー名 AS SELECT文;
```

### 実際の例

下記のビューを作成してみるとします。

```sql
CREATE VIEW test_view AS 
SELECT t1.id, t1.name, t1.age, t2.address, t2.city, t3.job
FROM sample_table1 AS t1
JOIN sample_table2 AS t2 ON t1.id = t2.id
JOIN sample_table3 AS t3 ON t1.id = t3.id
WHERE t1.age < 25 AND t2.city = '東京';
```

これにより、「AS」以降に記載したSELECTをその都度書かなくても、下記の簡単なクエリで実行できるようになります。
```sql
select * from test_view;
```

なお、注意点として、ビューはREAD専用であり、ビューに対してINSERT、UPDATE、DELETEはできません。
また、ビューへの参照権限があれば、元のテーブルへの参照権限は不問です。


## マテリアライズドビューとは？

PostgreSQLにはマテリアライズドビューという仕組みもあります。略してマテビューと呼びます。
PostgreSQL 9.3から実装されました。

ビューはデータの実体を持たないのに対し、
マテリアライズドビューでは対象のデータをキャッシュし、実体として保持することが特徴です。

### マテビューの利点
・複雑なSELECT文を都度書かずに済みます。
・データの実体を持つ分、ビューより処理が高速です。

### マテドビューの欠点
・元のテーブルが変更された場合、マテリアライズドビューが保持する実体は古いままであり、手動で更新する必要があります。

### マテビューの作成構文は下記です。
MATERIALIZEDと書く以外は、ビューの作成と同じです。

```sql
CREATE MATERIALIZED VIEW マテリアライズドビュー名 AS SELECT文;
```

### 実際の例

下記のマテビューを作成してみるとします。

```sql
CREATE MATERIALIZED VIEW test_mate_view AS 
SELECT t1.id, t1.name, t1.age, t2.address, t2.city, t3.job
FROM sample_table1 AS t1
JOIN sample_table2 AS t2 ON t1.id = t2.id
JOIN sample_table3 AS t3 ON t1.id = t3.id
WHERE t1.age < 25 AND t2.city = '東京';
```

件数を出してみると、8件でした。
```sql
select count(*) from test_mate_view;
```

この8件のデータのうち、2件のレコードを削除し、再度実行しても、変わらず8件のままです。
テーブルの実体をマテビューに反映するには、以下のコマンドを実行する必要があります。

```sql
REFRESH MATERIALIZED VIEW マテリアライズドビュー名;
```

今回の場合は、
```sql
REFRESH MATERIALIZED VIEW test_mate_view;
```

```sql
select count(*) from test_mate_view;
```
を再度実行すると、6件取得されました。

### マテビューの補足
PostgreSQLのマテリアライズドビューの更新（REFRESH MATERIALIZED VIEW）は、
完全リフレッシュといって、全てのレコードを更新し直す挙動になります。
OracleDBでは増分のみのリフレッシュを行うことも可能ですが、PostgreSQLでは未実装の機能であります。
コマンドの出力をリダイレクトする方法(Vim)

## はじめに

[dpp.vim](https://github.com/Shougo/dpp.vim) へIssueを作成するときに、 `:redir` というコマンドの実行を求められ、わからなくて調べたので紹介します。

## 環境

- OS：macOS Sonoma 14.0（23A344）
- Vim：9.0 Compiled by uhooi

## `redir` とは？

記事のタイトルの通りですが、コマンドの出力（メッセージ）をリダイレクトするコマンドです。

末尾が `dir` なので、ディレクトリに対して何か操作をするコマンドかと思いますが、「redirect」の略で、ディレクトリとは無関係です。

## `redir` の使い方

`redir` の使い方です。
最初は少しとまどいますが、慣れるとわかりやすいです。

```vim
" ファイルへリダイレクトする
" `redir!` で、すでにファイルが存在する場合は上書きする
" `>>` で、すでにファイルが存在する場合は追記する
:redir > test.txt

" 任意のコマンドを実行する
:echo 'Hello, Vim!'

" リダイレクトを終了する
:redir END
```

リダイレクトしたファイルを開いて中身を確認します。

```test.txt


Hello, Vim!
```

`:echo` の実行結果がファイルにリダイレクトされていることを確認できました。

## よく使うリダイレクト

よく使うリダイレクトを紹介します。

### メッセージをリダイレクトする

メッセージをリダイレクトします。

プラグインの不具合報告時によく使います。

```vim
:redir > messages.txt
:messages
:redir END
```

### ランタイムパスをリダイレクトする

ランタイムパスをリダイレクトします。

こちらもプラグインの不具合報告時によく使います。

```vim
:redir > rtp.txt
:set rtp
:redir END
```

## おわりに

コマンドの出力をリダイレクトする方法の紹介でした。
これでVimのコマンドの実行結果を簡単に共有することができます :relaxed:

## 参考リンク

- [various - Vim日本語ドキュメント](https://vim-jp.org/vimdoc-ja/various.html#:redir)
Socket.IOのクライアント用モジュールはなぜパス指定のみで読み込めるのか


[Socket.IO](https://socket.io/)のクライアント側のモジュールが、`node_modules`内に存在しているにも関わらず、`/socket.io/socket.io.js`というパス指定だけでクライアントサイドから読み込めることが非常にフシギに思った。
> The io method is bound to the global scope in the standalone build:
> ```html
> <script src="/socket.io/socket.io.js"></script>
> <script>
>   const socket = io();
> </script>
> ```
（[Socket.IO公式ドキュメントより](https://socket.io/docs/v4/client-api/)）

例えば、Bootstrapなどは[ここ](https://qiita.com/yutami/items/75d65de5d6f79143ee92)で解説したように、静的ファイルとして提供することをサーバーサイド側で定義しなくてはならない。

なぜ読み込めるのだろう？

# 結論
[Socket.IOのソースコード](https://github.com/socketio/socket.io/blob/main/lib/index.ts)を読むと、クライアント側から読み込めるようにしている処理があった。
```typescript:index.ts
// 省略

  public attachApp(app /*: TemplatedApp */, opts: Partial<ServerOptions> = {}) {
    // merge the options passed to the Socket.IO server
    Object.assign(opts, this.opts);
    // set engine.io path to `/socket.io`
    opts.path = opts.path || this._path;

// 詳しい処理は長いので省略

        const filepath = path.join(__dirname, "../client-dist/", filename);
        serveFile(res, filepath);
      });
    }

    patchAdapter(app);
  }
  
// 省略
```
`/socket.io`や`/client-dist`に関する内容が伺える。
# おわりに
クライアントありきのモジュールだからこのようになっているのは当たり前のことだが、
Node.jsを学習し始めた際に結構気になっていたことだったので、理解できてよかった。