OmniAICreator/Qiita-1.07M huggingface dataset:
Geospatial Hubのshpファイルからベクトルタイルを作成する

# はじめに
国連の[Geospatial Hubのページ](https://geoservices.un.org/webapps/geohub/)がCarto tileで使用されているベクトルタイルの元データとなっているので、その元データからベクトルタイルを作成してみることにします。本当はデータが少し異なるようですが、ほとんど同じようなので今回は練習としてGeoHubのデータを扱います。Carto tileは[こちらのページ](https://www.un.org/geospatial/mapsgeo/webservices)で見ることが出来ます。

# shpファイルをダウンロードする
Geospatial Hubのページから、Dataのページに飛びます。その中から、「UN Geodata stylized」を選択します。さらにArcGISのページに行くことで、データがダウンロード出来ます。データが非常に簡略化されているため、サイズは小さく342KBしかありませんでした。

# shpファイルの中身を確認する
ダウンロードしたｓｈｐファイルの中身をQGISで見てみます。ｓｈｐファイルが８つありますが、使用するデータは以下の２つです。
・BNDL_stylized(BNDLはBoundary Lineのことだと思われます。）
・BNDA_stylized(BNDAはBoundary Areaのことだと思われます。）

Coordinate Reference System (CRS)を見てみると、「Eckert IV (world)_2」というものが使用されています。

![スクリーンショット 2024-08-18 11.44.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/507a3136-31d2-06cc-3e2f-6ad3c985935a.png)

調べてみたところ、ArcGIS では、Eckert IV 投影法が標準でサポートされているようですが、QGISでは標準でサポートされていないようでした。始めはQGISでうまく変換出来ないか色々と試していましたが、無理でした。ArcGISではうまくいったので、そのやり方を記載します。

# shpファイルのCRSをArcMapで変更する
ArcMapを使用して、「Eckert IV (world)_2」から「WGS 1984(つまりEPSG:4326)」として、新しくshpファイルをエクスポートしました。作成したshpファイルを、QGISでレイヤ情報を表示してみると、CRSが「EPSG:4326 - WGS 84」となっていることが分かります。

![スクリーンショット 2024-08-19 10.55.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/ab8d6fc8-fac8-3352-3710-fcfe134f929f.png)


# shpファイルからベクトルタイルに変換する際の情報整理

後にスタイル付けをする際に必要になってくるので、この時点で整理しておきます。

| レイヤ名 | ソース | Min Zoom | Max Zoom |
|:-:|:-:|:-:|:-:|
| bndl | BNDL_stylized4326.shp  | 0 | 4 |
| bnda  | BNDA_stylized4326.shp  | 0 | 4 |

# shpファイルをGeoJSONファイルに変換する
次にCRSを変更したshpファイルをGeoJSONファイルに変換します。

```
ogr2ogr -f GeoJSON BNDL_stylized4326.geojson BNDL_stylized4326.shp
ogr2ogr -f GeoJSON BNDA_stylized4326.geojson BNDA_stylized4326.shp
```

QGISで作成したSHPファイル、GeoJSONファイルを表示したところ以下のようになりました。変換後も、正常に地図が表示されています。
![スクリーンショット 2024-08-19 12.27.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/72d9e7d2-5aee-18da-6f3f-3c262bd6b887.png)



# GeoJSONファイルからベクトルタイルに変換する
次にGeoJSONファイルからtippecanoeを用いて、ベクトルタイルに変換します。

```
tippecanoe -e VTstylized --no-tile-compression --no-feature-limit --no-tile-size-limit --drop-rate=1 -Z0 -z4 -L bndl:BNDL_stylized4326.geojson -L bnda:BNDA_stylized4326.geojson
```

作成したベクトルタイルデータは、[こちら](https://github.com/k96mz/20240818CartoTileStylized)のGithub Pagesで公開しています。アドレスは以下です。

https\://k96mz.github.io/20240818CartoTileStylized/Data/VTstylized/{z}/{x}/{y}.pbf

# まとめ
Geospatial Hubのshpファイルからベクトルタイルを作成しました。CRSの設定のところで、かなり時間を取られましたが、なんとかベクトルタイルを作成することが出来ました。次は作成したベクトルタイルを使用して、Carto Tileと同等の地図をMaplibre GL JSとMaputnikを用いて作成してみたいと思います。

# Reference

https://qiita.com/k96mz/items/49f9976ad6ed9fdd701a

https://qiita.com/k96mz/items/1f7e0f8e6e41e6a78cc6
(調査中)Mockitoを使用して、JavaでJarFileオブジェクトのopenConnectionメソッドをモックにする

手順
JarFileオブジェクトをモックする: Mockitoを使用して、JarFileクラスのモックを作成します。
openConnectionメソッドをモックする: モックされたJarFileオブジェクトがopenConnectionメソッドを呼び出した際に、モックされたJarURLConnectionを返すように設定します。
テスト内でモックを使用する: テストコード内で、モックされたJarFileを使用します。
以下はその例です。

```java
import static org.mockito.Mockito.*;

import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.jar.JarFile;
import org.junit.jupiter.api.Test;

public class JarFileTest {

    @Test
    void testOpenConnection() throws Exception {
        // 手順1: JarFileをモックする
        JarFile mockJarFile = mock(JarFile.class);
        
        // 手順2: JarURLConnectionをモックする
        JarURLConnection mockConnection = mock(JarURLConnection.class);
        
        // モックされたJarFileがopenConnectionを呼び出した際に、モックされたJarURLConnectionを返すように設定
        when(mockJarFile.getJarEntry(anyString())).thenReturn(mock(JarFile.JarEntry.class));
        when(mockConnection.getJarFile()).thenReturn(mockJarFile);
        when(mockConnection.getJarEntry()).thenReturn(mock(JarFile.JarEntry.class));
        
        // モックされたURLがモックされたJarURLConnectionを返すように設定
        URL mockUrl = new URL("jar:file:/some-jar-file.jar!/");
        URLConnection connection = mockUrl.openConnection();
        when(mockUrl.openConnection()).thenReturn(mockConnection);

        // 手順4: テスト内でモックを使用する
        // ここで、テスト対象のコードがJarFileとopenConnectionを使用します。

        // 例:
        JarFile jarFile = ((JarURLConnection) connection).getJarFile();
        // 必要に応じてアサーションやさらなる操作を行います
    }
}
```

ポイント:
JarFileとJarURLConnectionのモック: モックオブジェクトは、実際のオブジェクトの動作をシミュレートし、実際のファイルシステムやネットワークに依存せずにコードのインタラクションをテストできます。
メソッドのスタブ: when(...).thenReturn(...)を使用して、モック上で特定のメソッドが呼び出されたときの振る舞いを定義します。
この方法を使うことで、実際のJARファイルやネットワーク接続に依存せずに、JarFileやそのopenConnectionメソッドとやりとりするコードをテストすることができます。
Milk-V Duo 256Mを検証する

# Milk-V Duo 256Mをいただいたので検証してみる
先日2024年8月1日、東京大学伊藤国際学術研究センター 伊藤謝恩ホールで開催されたRISC-V Day Tokyo 2024 Summerにて、Milk-VのブースでDuo 256Mをいただきました。Milk-V Technologyの皆様、ありがとうございます。
筆者のひどい気まぐれと遅筆のせいで20日も経っておりました。

Milk-V Duoについてと64MB版についてはこの記事で解説しています。

https://qiita.com/niwatori_chicken/items/ff010f27906dd3a5a9a3

# ハードウェア的な違い
まず製品名からあるとおり、メインメモリが64MBから256MBに、実に4倍のアップグレードを遂げています。

64MB版に搭載されていたSoC、CV1800BについてはブランドはCVItekでしたが、CVITEKは2022年に[SOPHGOに買収されました](https://sophon.ai/about-us/index.html)。搭載されているチップはそのアップグレードであるSG2002になっています。

そしてメモリインターフェースがCV1800BではDDR2@16-Bitでしたが、Duo 256MではDDR3@16-Bitに変更されました。

TPUに関しても従来からテコ入れが入っており、64MB版が500GOPS@INT8であったのに対し、256MB版では1TOPS@INT8に向上しています。

メインとなるCPUコアとして、C906とは排他利用の関係になりますがCortex-A53が追加されています。

機能が多くなっているせいか、パッケージサイズが大きくなりました。CV1800Bが7×7mmであったのに対し、SG2002は9×9mmに増加しています。ボード上を目視するとすぐ見分けがつきます。

GPIOの方に目を向けると、オーディオ出力が追加されています。

# ソフトウェア的な違い
Buildrootをビルドするときのオプションが`milkv-duo256m-sd`に変わっています。有志によるDebianイメージなどもDuo 256M対応版が上がっています(DTBなどの差異かと思われる)。

カナメとなるCPUコア(Xuantie C906)自体は変わっていないので、アプリケーションの開発にあたってツールチェーン周りに手を加える必要はありません。

ただし、Buildrootをビルドする際にIONとメディアエンコーダーのメモリ割り当ての値を完全に0にすると起動・終了時にハングしたり、如何せん動作が不安定になったりすることを確認しています。現時点では0にはせず、縮める程度がよいでしょう。

# 結論
大きめのアップグレードではありますが、互換性は最大限確保してある印象です。特にメモリが物足りないなら64MBからの買い替えという線もアリかと思われます。
foobar2000で曲をドラッグドロップでプレイリストに追加した時に画面が切り替わらないように設定

# 概要

追加先のプレイリストへ画面がいちいち切り替わるのがわずらわしい時があります。

foobar2000は色々細かく設定ができるけど、自分の求める設定がどこにあるか探すのが大変な時あります。
「あれ、そういえばこの設定ってどこだっけ？っていうかそもそも設定ってできたっけ？」と忘れてしまった時用としてこの記事を用意。

# やり方

『Display』
『Columns UI』
『playlist switcher』
の
『Activate target playlist after dropping files』
をオフに。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/d6ef1884-b3d9-2413-6be4-e97810841a19.png)

# 参考サイトさん

https://foobar2000.xrea.jp/?Playlist+switcher+%E8%A7%A3%E8%AA%AC

# バージョン

Microsoft Windows [Version 10.0.22631.4037]
foobar2000 v2.1.5 [×64]
【Mac】ユニバーサルコントロール / ディスプレイ が途切れたときに再接続する

「設定」-「ディスプレイ」です。

![sc 2024-08-19 at 20.32.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588914/672d8121-69a6-01c0-02b8-4450af25c073.png)

コマンドラインでやると、

```shell
open "x-apple.systempreferences:com.apple.Displays-Settings.extension"
```

です。

頻繁すぎて面倒なので以下のように、ショートカット化しておくと良さげです。

https://android.benigumo.com/20240820/re-connect-univarsal-control/
jqueryライクにかけるライブラリを開発してみた。

# 経緯
多少、jsフレームワーク触ったり、jqueryでdom操作したりするぐらいで、そういえばあまり、jsの言語仕様を知らないなとお盆に気づきました。(jqueryが便利すぎて、思考停止でjqueryのプラグイン使ったりであまり知る機会が...)

ライブリ的なものを作ればjsの勉強にもなるし、古いブラウザ対応をしなければ、ファイルサイズも小さくなり、、小規模なものなら、活用できるかなと考えました。
やっぱり、ブラウザの差異が無くなったといってもjqueryのメソッドチェーンでのdom操作やslidetoggleなんかは、まぁ便利です。

↓開発したもの

https://github.com/teratai3/slimQuery

特に解説するような内容は無いのですが、jsでprivateが使えるようになっていたのは驚きました。
積極的にprivateを使ったのですが、プライベートを使うと遅くなるようです。(後から知りました...)

https://zenn.dev/waryu/articles/2dcc01d079db9a#%E7%B5%90%E8%AB%96

また、操作するメソッド事にモジュール化して、コードの見通しを高めています。
ビルドツールも駆使しようかと思いましたが、今回はお手軽に使えるPreprosでビルドしています。
今後、メソッドチェーンは、自分が考えた方法だと毎回メソッドを呼び出すたびにeachするはめになるので
処理の効率悪いかもと考えているので、他のjsライブラリ「Umbrella.js」「cash」辺りを参考にして改良したいと考えています。
競馬予想AIを作りたい（データ収集編２）

# 前回の話
とりあえずnetkeiba.comからデータを集めてきて学習させた。
一着を当てる問題として学習させたが、過学習するし精度は20％程度しか出なかった。
原因を考えた結果、全レース18頭立てというわけではないので、上手くいかないと仮定し、再挑戦することにした。

### 補足
前の記事で使っていたデータが吹っ飛んだため、データを収集し直しました。
この記事以降で扱うデータは、中央競馬の2008年～2022年の芝レースかつ、「未出走」「未勝利」「新馬」を除いた全14630レース分のデータを扱っていきます。
（芝に限ったのは、予測しやすくするため）

# 今回の話
仮定は違っていたようなので、データを見直すことにした。

## 仮定した結果は影響なし
18頭立てのレースだけに絞って学習させたが、特に傾向が変わることは無かったので失敗に終わった。
ついでにデータを増やし、レース場や距離、馬体重や増減、性別も加えてみたが、これも対して変わらなかった。
（面倒になったので、レース場と距離、性別は外すことにした）

## データの見直し
### 着順と他の項目の相関を見る
ひとまず、着順予想に使える項目がどれか見直すために相関行列を出してみた。
今回収集したデータは18頭立て想定で収集しているが、16頭立ての場合17,18番のような足りない部分は0で埋めている。
それらを除外して相関係数を求めたグラフとなっている。
![corrr_map.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382806/6d110b47-1839-c406-d82a-2629c5ca347d.png)


これを見ると、着順と最も強い相関があるのは人気の0.57。
次いで相関があるのは単勝の0.44。
前走までの順位はせいぜい0.2程度しか無い。
年齢は0.12と低いながらも相関があるので、若いほど強いということだろう。
馬番は僅かに相関があるが、内枠有利であることを示しているのだろうか。
逆に、馬体重や増減、前走からの日数は影響していないことが分かる。

### 着順と人気、単勝オッズの関係を見る
着順と人気でクロス集計してみた。
![pop_res.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382806/f0524f6f-9640-e104-8887-34e54bd17d52.png)

分かりにくいが、左上に行くほど人気が高く成績も良い。
右下に行くほど人気が無く成績も悪い。

こう見ると、人気1位が約4400回勝っている。
人気2位が1着になるのが約2700回程度。
以降、人気5位あたりまでは約1000回勝っていることが分かる。
このデータは14630レース分なので、人気1位だけを買い続ければ3割程度の的中率になる。

--

今度は着順とオッズで散布図を出してみた。
![odds_res.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382806/4c519e75-56b3-d848-29fd-17fbae91f790.png)

基本的にオッズが低いほど良い成績ではあるが、オッズが低くても悪い成績になることはよくあるらしい。
概ね200倍以下なら1着の可能性が（比較的）高いことが分かる。

ちなみに、人気1位だけに限ってオッズと着順の散布図を出すとこんな感じ。
![odds_res_at1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382806/781f6789-6597-f2c2-c284-d2052ba50f3a.png)

なんかよく分からんが、一応オッズが低いほど着順は良いことが分かる。

# 今回の結論
~~いかがでしたか？調べてみたけどよく分かりませんでした！~~
とりあえず、今あるデータは着順と無相関ばかりというほど無意味では無いので（認めたら負けな気がするので）、今度はAIのネットワーク構造を見直すことで改善を期待したい。

InceptionNetのアイデアとかDilated Convolutionとか上手いこと組み合わせれば上手く行ってくれると良いなぁ。
【アイディア】リレープログラミング


## 概要

競技っぽいの。
イベントとか親睦を深めるために使う。
リレー小説のプログラミング版みたいな感じ。

## 詳細

1チーム3～5人であるテーマに沿ってプログラムを作る。
プログラムを書き一定時間が経過したら次の人にプログラムを渡すことを繰り返す。
最後の人で一定時間が経過したら最初の人にプログラムを渡す。

最終的に最も速くプログラムを完成させたチームの勝ち。
もしくは制限時間を設けて、もっとも出来の良いプログラムを作ったチームの勝ち。

言うまでもないが、プログラムを書いているときは他人が干渉することは禁止。
テーマはググったり、AIで楽に実装できるものは望ましくない。
変則オセロなど凝ったものだと面白いかもしれない。
awkでオプション解析（getopts相当の実装）

## はじめに

awk でオプション解析を行いたかったのでシェルの `getopts` 相当の機能を持つ関数を実装しました。ロングオプションなどには対応していません。gawk だけではなく POSIX に準拠したどの awk の実装でも動作します。

## awk 版 getopts の実装

`getopts` という関数名にしていますが、シェルの `getopts` コマンド互換のインターフェースにするつもりはありません。

```awk
function getopts(optstring, args,  i, j) {
  i = OPTIND ? int(OPTIND) : (OPTIND = 1)
  j = int(substr(OPTIND, length(i) + 2))
  OPTERR = OPTARG = ""
  if (!(i in args)) return 0
  if (args[i] == "--") { OPTIND = i + 1; return 0 }
  if (args[i] !~ /^-./) return 0
  OPT = substr(args[i], j + 2, 1)
  OPTARG = substr(args[i], j + 3)
  if (index(optstring, OPT ":")) {
    if (OPTARG == "") {
      if (!(++i in args)) {
        OPTERR = "option requires an argument -- " OPT
        OPTARG = ":"
        return 0
      }
      OPTARG = args[i]
    }
    OPTIND = i + 1
  } else if (OPT != ":" && index(optstring, OPT)) {
    OPTIND = (OPTARG == "") ? (i + 1) : (i "," (j + 1))
  } else {
    OPTERR = "illegal option -- " OPT
    OPTARG = "?"
    return 0
  }
  return 1
}
```

## 使い方

上記の関数を awk スクリプトの冒頭に埋め込んだりして実行してください。以下はシェルスクリプトに埋め込んだ場合のサンプルコードです。

```sh
#!/bin/sh

${AWK:-awk} "$(cat getopts.awk)"'
  BEGIN {
    while(getopts("fgo:p:", ARGV)) {
      if (OPT == "f") print OPT
      if (OPT == "g") print OPT
      if (OPT == "o") print OPT " : " OPTARG
      if (OPT == "p") print OPT " : " OPTARG
    }
    if (OPTERR) {
      printf "%s (OPT: %s, OPTARG: %s)\n", OPTERR, OPT, OPTARG
      exit 1
    }
    print "Arguments:"
    for (i = OPTIND; i < ARGC; i++) {
      print ARGV[i]
    }
  }' "$@"
```

以下のグローバル変数を使用します。

- `OPTIND` 次にオプションを解析する引数位置
  - 新しいオプション解析を始める時は1に設定すること
- `OPT` 読み込んだオプション
- `OPTARG` オプション引数（存在する場合）
- `OPTERR` エラー時のメッセージ

`getopts` はオプション解析の終了またはエラー時に偽を返します。エラー時には `OPTRERR` にエラーメッセージを `OPTARG` にエラーの種別を設定します。

- `OPTARG` エラーの種別
  - `?` 不正なオプション 
  - `:` オプション引数が必要な場面で、オプション引数が存在しない場合

## その他の実装

gawk でも getopt.awk という同等の処理を行う関数が Public Domain で提供されています。こちらはロングオプションにも対応しているようです。

https://git.savannah.gnu.org/cgit/gawk.git/tree/awklib/eg/lib/getopt.awk

ロングオプション対応を除いて機能的には大差ないのですが、少々使い方やコードが冗長に感じたので再実装しています。

## さいごに

このコードのライセンスは今のところ特に指定していませんが自由に使用してください。リポジトリを以下にあります。

https://github.com/ko1nksm-shlab/getopts.awk
SSR, CSR, MPA, SPA, SSG の簡単な覚え方

# はじめに

混乱しやすい技術たちの名前を自分の備忘録として書く。

# SSR (Server Side Rendering)

**覚え方:** サーバー(Server) 側(Side) でレンダリング(Rendering) を行う

**処理:** サーバーで**html**を生成し、ユーザーが(各ページに)リクエストするとすぐに**完全なページが返される**(各ページで)。初回表示はサーバーで処理されるため、素早く表示される

# CSR (Client Side Rendering)

**覚え方:** クライアント(Client) 側(Side) でレンダリング(Rendering) を行う

**処理:** ページのコンテンツは、ユーザーのブラウザで**JavaScriptが動的に生成する**。サーバーからは最低限の**html**やデータが送られ、ブラウザがそれを元にページを作る

# MPA (Multi Page Application)

**覚え方:** 複数の(Multi) ページ(Page) で構成されているアプリケーション(Application)

**処理:** 各ページが独立しており、ユーザーが**新しいページに移動するたび**、サーバーから新しい**html**がロードされる。従来のウェブサイトに近い動作

# SPA (Single Page Application)

**覚え方:** 1つの(Single) ページ(Page) (かのように)構成されているアプリケーション(Application)

**処理:** 最初に1つの**html**ページがロードされ、その後のページ遷移やコンテンツの変更はJavaScriptで動的に行う。実際にはページ全体がリロードされることなく、**アプリケーションのように動く**

# SSG (Static Site Generation)

**覚え方:** 静的な(Static) サイト(Site) を生成(Generation)

**処理:** サイトをビルドする時点で、すべてのページを静的な**html**ファイルとして生成する。**これらのファイルはサーバーに保存され**、ユーザーがアクセスするとそのまま提供される

# イメージ連想

**SSR:** サーバーが頑張る

**CSR:** クライアント(ブラウザ)が頑張る

**MPA:** ページごとに処理する

**SPA:** 全部一つの場所で処理する

**SSG:** あらかじめ作っておく

# まとめ

1つのアプリケーションやサイトで上記の複数の技術が組み合わさって使われることもあるので
あまり難しく考えすぎないことも重要だと思った。
Javaで指定のファイルがテキストファイルかどうか判定する

Javaを用いて指定のファイルがテキストファイルかどうかを判定する方法を調べたので備忘録としてまとめます。

[Apatch Tika](https://tika.apache.org/)を用いてファイルの[MIME TYPE](https://developer.mozilla.org/ja/docs/Web/HTTP/Basics_of_HTTP/MIME_types)を判定してもらう方法が手軽にできてよかったです。

Mavenのライブラリをインポートします。
```xml:pom.xml
<dependency>
    <groupId>org.apache.tika</groupId>
    <artifactId>tika-core</artifactId>
    <version>2.9.2</version>
</dependency>
```

Apache Tikaを使ってファイルがテキストファイルかどうかを判定するコード例です。

```java
import org.apache.tika.Tika;
import java.io.File;
import java.io.IOException;

public class FileTypeChecker {

    public static boolean isTextFile(File file) {
        Tika tika = new Tika();
        try {
            String mimeType = tika.detect(file);
            System.out.println("Detected MIME type: " + mimeType);
            return mimeType.startsWith("text/");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    public static void main(String[] args) {
        File file = new File("sample.txt");
        if (isTextFile(file)) {
            System.out.println(file.getName() + " is a text file.");
        } else {
            System.out.println(file.getName() + " is not a text file.");
        }
    }
}
```

## コード例の概要

1. `Tika tika = new Tika();` を使用してTikaのインスタンスを作成します。
1.  `tika.detect(file)` メソッドを使って、ファイルのMIMEタイプを検出します。たとえば、テキストファイルであれば `text/plain` などが返されます。
jsonファイルは `application/json` となるので適宜判定処理を修正しましょう。
1. MIMEタイプが「`text/`」で始まるかどうかを確認
【Next.js】pino-prettyの導入方法

Next.jsでPinoを使用している場合にpino-prettyの設定を以下のように記述するとエラーが発生します。

```logger.ts
const pino = require('pino')

const logger = pino({
  transport: {
    target: 'pino-pretty',
    options: {
      colorize: true
    }
  }
})

```

```terminal
 ⨯ uncaughtException: Error: the worker has exited
    at ThreadStream.write (webpack-internal:///(rsc)/./node_modules/thread-stream/index.js:238:19)
    at Pino.write (webpack-internal:///(rsc)/./node_modules/pino/lib/proto.js:217:10)
    at Pino.LOG [as debug] (webpack-internal:///(rsc)/./node_modules/pino/lib/tools.js:62:21)
    at fetchData (webpack-internal:///(rsc)/./src/utils/api/fetch-data.ts:40:62)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async eval (webpack-internal:///(rsc)/./src/utils/api/server/validate-token.ts:24:29)
    at async CurrentUserInfo (webpack-internal:///(rsc)/./src/components/pages/account-page/current-user-info/index.tsx:59:33)
```

エラーを回避するには`next.config.js`に以下を追記します。

```next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    serverComponentsExternalPackages: ['pino'],
  },
};

module.exports = nextConfig;

```

`serverComponentsExternalPackages`はNext.js v15.0.0から安定版となるため、以下のように書き換える必要があります。

```next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  serverExternalPackages: ['pino'],
}
 
module.exports = nextConfig

```

## 参考

https://github.com/orgs/vercel/discussions/3150#discussioncomment-8044308
push後にgithubのauthorとcommiterを変更する方法

夫婦でMacBookを共有しており、設定など全て夫が行っているため、あらゆる権限が夫で設定されています。

そのため、ターミナル経由でgitへcommit&pushした際にauthorとcommiterに夫のフルネームが表示されてしまっていました。

commit&push後でしたが、authorとcommiter名を変更して修正しました。

## authorとcommiterの変更

ターミナルに下記全てをコピペ。
```
% git filter-branch --env-filter '
OLD_EMAIL="old@example.com"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="new@example.com"

if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$CORRECT_NAME"
    export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$CORRECT_NAME"
    export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags
```

下記部分を自分の名前やメールアドレスに変更します。

OLD_EMAIL="変更前のemailを入力"
CORRECT_NAME="修正表示したい名前を入力"
CORRECT_EMAIL="修正表示したいemailを入力"

OLD_EMAILに登録されている変更前emailを調べる方法はターミナルにて下記。
```
% git log --pretty=full
```

私はの場合は、"夫の名前\<username|@Usernames-MacBook.local\>"と出てきたが
\<\>内のMacBook.localのアドレスで問題なく入力できた。

## 強制pushする
```
git push --force --tags origin 'refs/heads/*'
```
すでにpush済みのため強制pushで更新が必要。

![スクリーンショット 2024-08-19 23.44.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3690542/2f08f601-ad3b-7b41-f917-1df59679d792.png)

夫の名前が表示されていた部分に自分のusernameに変更された。

## 設定を確認＆変更
毎回間違わないよう、今後のcommiterとauthorを変更しておく。

現在の設定を確認。
```
git config --list
```

設定があればusernameとemailが表示される。

```
git config --global user.name "username"
git config --global user.email ~~~~~~@email.com
```

リポジトリごとの変更は上記で"--global"を削除する。

## まとめ
家族でパソコンを共有していたり、いつもと違う環境からのcommitやpushは事前にconfigで設定を確認する必要があると学びました。
Mac でファイルを圧縮すると Windows で解凍するとき文字化けする

## 概要

Mac で圧縮した ZIPファイルを Windows で解凍すると、ファイル名やフォルダ名は文字化けすることがあります。特に日本語のファイル名やフォルダ名を使用している場合、この問題は顕著に現れます。この記事では、文字化けの原因とその対処法について解説します。

## 原因

文字化けの主な原因は、Mac と Windows で使用されている文字コードの違いです。Mac はファイル名のエンコーディングに「UTF-8」を使用しており、Windows は「Shift_JIS」を主に使用しています。この違いにより、Mac で作成された ZIPファイルを Windows で解凍すると、文字コードが適切に解釈されず、結果として文字化けが発生します。

## 対処法

文字化けを防ぐためには、以下の対処法があります。

#### 1. ファイル名を半角英数字に変更する

圧縮する前に、ファイルやフォルダの名前を日本語から半角英数字に変更することで、文字化けを防ぐことができます。

#### 2. 圧縮・解凍ツールを使用する

Windows 側で文字化けを防ぐために、Mac と Windows 間の文字コードの差異を自動的に処理する解凍ツールを使用する方法があります。これにより、文字化けせずにファイルを正しく解凍できます。

例) 7-Zip

https://7-zip.opensource.jp/

#### 3. Windows 用の ZIP圧縮形式を使用する

Mac で ZIPファイルを作成する際に、Windows 互換の圧縮形式を使用することで、文字化けの問題を予防できます。これにより、Windows での解凍時に文字化けが発生しにくくなります。

例) DTP Zipper

https://tama-san.com/app-page/dtp-zipper.html
AWS Lightsailのはじめかた～インスタンスの作成とSSH接続～

# やったこと
AWSのLightsailを使って、UbuntuにSSH接続するところまでやってみました。

# 環境
* Amazon Lightsail
* Ubuntu 22.04 LTS
* RLogin

# 手順
1. AWSにログインしてLightsailを検索する
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454725/88a051c9-9bc5-bb6f-efef-0a9e5fa12a4b.png)
1. インスタンスの作成をクリック
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454725/91557873-2819-10a7-878a-b11577782aa0.png)
1. とりあえずOS(Ubuntu)のみ
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454725/5d8d21f7-4e1f-53e7-99e0-df3711b7702f.png)
1. 一番お安い$5を選択
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454725/f93aefda-48a8-5ba0-0f5d-1cc1497d4eb8.png)
1. リソース名を入力して「インスタンスの作成」をクリック
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454725/0d885cca-f8d4-03e5-18a6-349202c06a00.png)
1. 「保留中」＝インスタンス作成中なのでしばらく待ちます
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454725/8514a8d0-f692-9b67-1b49-9af8488e909a.png)
1. インスタンスの作成が終わると「実行中」になります
※「保留中」のまま放置して翌朝確認したので「おはようございます！」:grin:
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454725/9efc8692-359c-0887-bda6-7bbc081a3ecc.png)
1. リソース名「Ubuntu-web」をクリックするとインスタンスの詳細が確認できます
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454725/b8512a1b-7860-7e4c-4e9b-0d7ed728aa20.png)
1. 「SSHを使用して接続」でブラウザベースのSSHクライアントも使えますが、
独自のSSHクライアント（今回は[RLogin](https://kmiya-culti.github.io/RLogin/)）を使います
    * 「接続先」のIPアドレス、「ユーザー名」をメモします
    * 「デフォルトキーのダウンロード」をクリックしてPEMファイルをDLします
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454725/d91e3487-d231-e56d-4a43-61a1dd6a1fc7.png)
1. RLoginを起動し、「新規」ボタンをクリックします
※[RLogin](https://kmiya-culti.github.io/RLogin/)のインストール方法等はサイトを確認してください
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454725/5410659e-23c1-b214-3ae5-ffc2aea3e4e8.png)
1. 任意のエントリー名、メモしたIPアドレス、ユーザー名を入力します
「SSH認証鍵」をクリックします
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454725/a01c40c5-da0d-8a27-70f7-2eee209b7745.png)
1. DLしたPEMファイルを選択します
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454725/785a308c-625c-d862-a7d2-d3c6a2173dbe.png)
1. 「接続する」をクリックします
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454725/1dd39ac9-638d-b9da-0d7d-9c6b199b014a.png)
1. SSHで接続できました
![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454725/6da78cb1-db3e-c477-9d36-e89ac391646b.png)
# まとめ
とりあえず必要最低限の手順をまとめてみました。
静的IPをアタッチしていないので、インスタンスを停止して起動するとIPアドレスが変更されます。ご注意ください。
インスタンスの再起動ではIPアドレスは変わらないみたいです。もちろんSSHで接続中であれば切断されますが。
【合格体験記】Oracle Master Silver DBA 2019(1Z0-082)

## はじめに
2024/07/12にOracle Master Silverの試験を受け、無事合格しました。
誰かの参考になればと思い、記させていただきます。

#### 筆者スペック
- 運用系エンジニア　配属からちょうど1年
- 業務でのDB利用はSQL投げる程度
- 4月にOracle Master Bronze取得

## 資格について
OracleMaster系の資格は2019から体系が変わったそうです。
こちらのサイトが個人的には参考になりました。
[・ORACLE MASTER 2019新資格体系とは – 18c/19c対応](https://cosol.jp/techdb/2020/02/new_oracle_master_overview_2020/#DBA%E7%B3%BBORACLE_MASTER%E8%B3%87%E6%A0%BC%E9%9A%8E%E5%B1%A4%E3%81%A8%E8%A9%A6%E9%A8%93%E7%A0%94%E4%BF%AE)

### OracleMasterSilverDBAとは
OracleMasterSilverにはDBAとSQLの二種類があります。
SQLでは内容のほとんどがSQLの文法らしいですが、
DBAではSQLに加えて、DBの管理や動作など、BronzeDBAを発展させたような内容が範囲となっています。

## 再試験無料期間について
Oracle系の資格って、例年春あたりで再試験無料キャンペーンがあるようです。
- [2024](https://www.pearsonvue.co.jp/Clients/Oracle/Special-Offers/Retake2024.aspx)
- [2023](https://blogs.oracle.com/oraclemaster/post/retake23jp#:~:text=2023%E5%B9%B43%E6%9C%881,%E3%82%92%E5%86%8D%E5%8F%97%E9%A8%93%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82)

申し込みは例年5月末まで、実際の受験は7月半ばまで可能となっています。

## 勉強方法
#### ①ping-t
WEB問題集のping-tを使いました。
OracleSilverSQLは無料コンテンツとなっており、登録すれば利用可能になっています。
問題数は587問ありますが、残念ながらSilver **SQL** の内容となっています。
SilverDBAの試験におけるSQLの範囲の勉強には役立ちます。

#### ②オラクルマスター教科書（黒本）
『オラクルマスター教科書　Silver DBA Oracle Database Administration I』
通称黒本をKindleで購入しました。
練習問題や模擬試験も含まれているので非常に役に立ちました。
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2088977/72c7b43d-5cae-b69d-e980-f3057361915a.png)
](https://www.amazon.co.jp/%E3%82%AA%E3%83%A9%E3%82%AF%E3%83%AB%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC%E6%95%99%E7%A7%91%E6%9B%B8-Silver-Oracle-Database-Administration/dp/4798166359)

2か月くらいはping-tやkindle黒本を暇なときにチラチラ見たりしていました。(週に1時間程度)
真剣に勉強した日数は2週間程度だったと思います。（一日1.5時間～3時間）

## 試験当日
ピアソンVueというシステムで受験申込をするのですが、テストの形式は2パターンあります。
普段はテストセンターで受験しているのですが、都合の良い試験日が予約できず、初めて在宅での受験(OnVue)をしてみました。
在宅形式自体の感想ですが、部屋の状態次第では便利かと思いました。
というのも、テーブルの上や手の届く範囲に不要なものを置いてはいけないというルールがあり、かつPCのカメラをオンにしておく必要があるので、
ちゃんと整っていない部屋だと受験できないんですよね。。。
今回は自室ではなく家族の部屋を使わせてもらって受験しました。
また、他の在宅受験体験記を見てみると、身分証明書でパスポート必須など書いてあることがあったのですが、今回は運転免許証とマイナンバーカードで通りました。

## 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2088977/bac04768-8845-b96a-e124-87d887f7697d.png)

無事合格です。

## 感想
正直、思ったより難しかったです。
試験中はわからない問題が結構あるなーと思いつつ、6割は取れそうだなといった感じです。
やはり黒本で出た問題に似ている内容や、理解していれば一瞬で解けるような問題がある程度は出題されるので、不安になりつつも合格できそうなレベルかと思います。

Bronzeの時は、「あまり実務には役立たなさそう」と思っていましたが、SilverではSQLの内容が含まれることや、DBAもより深い内容に踏み込めたので、今後に活きる知識が得られたかなと感じました。
自分の職場ではDBの管理はほぼ別部署が担当しているのであまりDBAに触れる機会はないのですが、意外なところで役に立ったことがあったので（具体的には動的パフォーマンスビュー、停止オプションなどが運用業務で参考になりました）勉強してよかったです。

ただ、Oracle完全に理解した状態になるには、やはりGoldは必要になりそうですね。実務でもGold以上の範囲の内容が必要になったケースがあったので（実行計画、srvctlコマンドなど）
落ち着いたらOracleMasterGoldを取得したいですね。
ただ、次に控えるのは10月のデータベーススペシャリストです。
がんばります。

以上！
【個人開発】便利ツールサイト「Ruby Tools」を作ってみた

こんにちは！今回は、私が個人開発で作成した便利ツールサイト「Ruby Tools」について紹介します。プログラマーだけでなく、一般のユーザーの皆さんの日常的なタスクを効率化するためのツールを集めたサイトです。

## Ruby Toolsとは？

Ruby Toolsは、様々な職種や個人が日々の作業で使える便利なツールを集めたウェブサイトです。ポモドーロタイマー、抽選ツール、六曜/大安カレンダー、IPアドレス確認ツールなど、多岐にわたるツールを一箇所にまとめました。

サイトURL: [https://nomin.jp/rubytools/](https://nomin.jp/rubytools/)

## なぜ作ったの？

日常生活やビジネスシーンで「このツール、どこかにないかな？」と思うことが多々ありました。そこで、よく使うツールを一箇所にまとめたサイトがあれば便利だと考え、Ruby Toolsを開発することにしました。

## 主な機能

Ruby Toolsには2024年8月19日時点で20個のツールがあります。
具体的な機能については実際にサイトでご確認ください！

## 誰のためのツール？

Ruby Toolsは幅広いユーザーを対象としています：

- **一般ユーザー**: ポモドーロタイマー、抽選ツール、六曜/大安カレンダーなど
- **ブロガー・ライター**: 文字数カウント、見出し/hタグ抽出ツール、画像圧縮ツールなど
- **デザイナー**: Webサイト画像抽出ツール、背景透過ツール、アスキーアート生成ツールなど
- **プログラマー**: IP情報確認ツール、Base64エンコード/デコードツール、16進数/HEX変換ツールなど

## 使用技術

- フロントエンド: HTML, CSS, JavaScript
- ホスティング: GitHub, Vercel

## 今後の展望

1. **新機能の追加**: ユーザーからのフィードバックを元に、新しいツールを随時追加していく予定です。
2. **モバイルアプリ化**: スマートフォンアプリとしても利用できるよう開発を検討中です。

## まとめ

Ruby Toolsは、プログラマーに限らず、様々な職種や個人の日常的なタスクを効率化するためのツールサイトです。個人開発ではありますが、多くの方に使っていただけるよう、日々改善を重ねています。

ぜひ一度使ってみて、フィードバックをいただけると嬉しいです。また、GitHubでソースコードを公開していますので、コントリビューションも大歓迎です！

最後まで読んでいただき、ありがとうございました。皆さんの日常生活やお仕事が少しでも効率的になれば幸いです。

## 参考リンク

- [Ruby Tools公式サイト](https://nomin.jp/rubytools/)
- [GitHub リポジトリ](https://github.com/nomindes/Ruby-Tools)
- [開発者Twitter](https://twitter.com/nomin_coding)
macOSのデスクトップアプリを開発している時、ローカルで実行しているアプリのローカルデータベースに保存されているデータを削除したい

Xcodeを使ってmacOSのネイティブアプリを開発している時、アプリのローカルデータベースに保存されているデータを全部消したい時があります。例えば自分の場合は、SwiftDataを使ってアプリを開発していて開発中のSwiftDataのモデルを変更した時です。開発中にデータモデルを変更したくらいでマイグレーション処理を書く必要はないので、単純にデータベースを削除したいのです。何故なら、そのままアプリを実行すると以下のようなエラーが発生してアプリを起動できなくなるためです（エラーメッセージはうろ覚えです）。

```
error: addPersistentStoreWithType:configuration:URL:options:error: returned error NSCocoaErrorDomain (134110)
```

```
Cannot migrate store in-place: Validation error missing attribute values on mandatory destination attribute,
```

上記のエラーは、既に作成されているテーブルに、後から追加したモデルのプロパティが存在しないため発生します。ローカルデータベースを削除して再起動すれば、テーブルが存在しない状態からアプリを起動することになるので、新たなスキーマでデータベースが作成されます。そのため、開発中にデータモデルを変更した場合は単純にデータベースを消してからアプリを起動したいのです。

が、これがなかなか難しい。開発中のアプリをアンインストールする方法がまずわからないし、開発中のアプリのバイナリを削除してもデータベースは削除されませんでした。

以下のSOの記事を読み、 `~/Library/Containers/your.app.bundle.here` に関連データが保存されていることを知りました。

[xcode - How to remove macOS app from device during development - Stack Overflow](https://stackoverflow.com/questions/75953216/how-to-remove-macos-app-from-device-during-development)

`your.app.bundle.here` を削除した後、再度Xcodeからアプリをrunすると、新たなスキーマでアプリを起動することができました。まあ、それまでローカルに溜まっていたデータは全部消えますが。
OSPFについて

# はじめに
OSPFの勉強をしてからずいぶんと復習できていなかったので、
OSPFの復習もかねて改めて勉強します。私自身の知識の再習得が目標です。

# OSPFとは

OSPF(Open Shortest Path First)は、主に同じAS内で使用されるIGP型のプロトコルで、大規模なネットワークに適している。また、お互いのルータがLSAを交換しあい、LSDBを形成する。以下にOSPFの基本的な仕組みについて説明します。

###### 1.リンクステート型プロトコル
　・各ルーターは、自分に直接接続されたルーターやネットワークの状態をしめす「リンクステート広告(LSA)を生成し、OSPFの同じエリア内の全ルーターと共有する。そして共有したLSAをトポロジテーブルに格納し、それからトポロジマップを形成。これは各ネットワークまでの最短パスツリーを表したもの。LSDBともよばれる。OSPFでは30分ごとに各ルーターとLSAの同期を行います。またトポロジに変更があった場合はトリガーアップデートで即座にLSAをエリア内の全てのルーターにアドバタイズする。


 ###### 2. エリアの概念
 ・ospfのエリアとは「LSAを交換する範囲をしめす論理グループ」の事。バックボーンエリアが全エリアを接続します。

 ###### 3.コストメトリック
 ・OSPFは、リンクの帯域幅に基づいてコストを計算し、最短パスツリー（SPT）を構築する。帯域幅が高いほどコストが低くなる。

 # OSPFの動作の流れ
 ##### 1.ネイバー関係の確立
 ・OSPFルーターは、helloパケットを送受信して隣接するルーターとネイバー関係を確立する。helloパケットにはルーターIDやデッドインターバルの情報が含まれる。
 ##### 2.LSAの交換
 ・ネイバー関係が確立されると、ルーターはLSAを交換し始めます。LSAは接続されているネットワーク情報が含まれる。
 ##### 3.LSDBの作成
 ・受信したLSAを元に、各ルーターは自分自身のリンクステートデータベース（LSDB）を更新する。LSDBは、ネットワーク全体のトポロジ情報を持っている。
 ##### 4.最短パスツリー（SPT）の計算
 ・LSDBの情報をもとに、最短パスツリーを計算し、ルーティングテーブルを更新する
 ##### 5.ルーティング情報の更新
 ・ネットワーク内でトポロジの変化が発生したとき、LSAが再度生成され、エリア内の全ルーターに配布。各ルータは再度SPTを計算し、ルーティングテーブルを更新する。
 # OSPFの利点
 ・エリア分割により、大規模なネットワークでも運用可能
 ・コンバージェンスが早い
 ・各リンクにコストを割り振る事で効率的なルーティングが可能
 ・可変長サブネットマスク（VLSM）に対応し、柔軟なアドレッシングが可能
# OSPFで使用されるパケットについて

##### 1. helloパケット
helloパケットは、OSPFルーターが隣接するルーターを発見し、隣接関係を確立、および維持するために使用される。
##### 2.DBDパケット
Database Descriptyon（DBD)パケットは、OSPFの隣接関係を確立したあとに使用され、LSDBの概要を交換する。DBDパケットにはLSAの要約情報が含まれる。
###### 3.Link State Requeest（LSR）パケット
LSRパケットはLSDBの足りない情報を要求するためのパケット
###### 4.Link state Update(LSU)パケット
・新しい、または更新されたLSA情報を隣接ルーターに送信するパケット
##### 5.Link State Acknowledgment(LSAck)パケット
LSUパケットで受信したLSAの受領を確認するためパケット

# DR,BDR,DRotherについて

OSPFでは、マルチアクセスネットワークにおいて、DR（Designated Router)、BD（Backup Designated Router）、DRother(DR以外のルータ）が選出される。それぞれの役割を解説

_DR_
マルチアクセスネットワーク上で選出されるルーター
他の全てのルーターとの間でLSAを管理・中継する

_BDR_
DRが故障したときのバックアップ。DRと同様全てのルーターからLSAを受け取るが、中継は行わない
_DRother_
DRotherはDRおよび、BDRと直接通信し、LSAの送受信を行う。


# アウトプット企画#1の反省点
OSPFの知識が曖昧でアウトプットではなく、インプットになってしまっていた。ただ、記事にするにあたってたくさんのブログや記事に触れたので普段のインプットより質の高いインプットができたと言えるが、アウトプットを目的にしているため次回ではその点を改善したい。しかし、アウトプットをするために必要なインプットが全くできていないことも感じた。明日はパケットトレーサーにチャレンジし、コマンドを1つずつ確認していくような記事を書きたい。
【Docker Desktop】Privileged Helper が許可を求めてくるようになった【解決】

# TL;DR

Docker Desktop バージョン4.33.0で起きてたWSL関連のバグで、PCを再起動する度に権限昇格ダイアログが表示される。
手っ取り早く解決したい方は[対処法 🛠️](#対処法-🛠️)を参照してください。

~~（おそらくすぐに修正版が配信されると思うので、この記事の寿命は短いはず）~~

:::note info
2024/09/05にDocker Desktop v4.34.1がリリースされ、この事象も解消されています。
:::


https://docs.docker.com/desktop/release-notes/#4341


# 事象 ⚠️

Docker Desktopを4.33.0, 4.33.1にアップデートしたところ、起動時に「Docker Desktop Privileged Helper」がPCへの変更許可を求めてくるようになった。

（Windows で管理者権限でアプリを起動したときなどになるアレです。スクショなし）




# 原因 🐞

GitHubにIssueが上がっていた。

https://github.com/docker/for-win/issues/13806

バージョン4.33.0のバグで、WSLのバージョンを認識し間違えて権限昇格ダイアログを表示するらしい。よってWindows限定かな？PCを再起動する度にこれが毎回表示される。
許可すれば問題なく動くが、ちょっと嫌。


# 対処法 🛠️

:::note info
2024/09/05にDocker Desktop v4.34.1がリリースされ、この事象も解消されています。
:::

https://docs.docker.com/desktop/release-notes/#4341

---

同Issueの中でいろいろ対処法は述べられている。

- Docker Desktopを最新バージョン（4.33.1）にアップデートする
    - -> これはやってみたが駄目でした。4.33.0を経由してそのままアップデートすると意味ないのかも
- Docker Desktopを最新バージョン4.33.1の開発用ビルドをインストールする
    - -> ~~これで直りました。個人的に推奨。~~ <font color=red> 一度直ったように見えたが、PC再起動後開発用ビルドを使っていることによる警告が出た</font>

https://github.com/docker/for-win/issues/13806#issuecomment-2271507065

- <b><font color=green>Docker Desktopの再インストール</font></b>
    - -> 結局これ

その他、試してはいませんが以下のようなものも提案されています。
- WSLを最新版に更新する
- .wslconfig にカスタムカーネルが指定されている場合、それをコメントアウトする


# まとめ

最近はよく分からない新し目っぽいエラーに遭遇したときXでキーワードを検索するようになりました。今回のIssueもXのポストで見つけました。
CodeCommitからリポジトリの一覧を取得する


## 準備
awsコマンドが使える状態であること

参考

https://zenn.dev/bluesdd/articles/5e45b45c2afd11

## リポジトリ取得コマンド
```bash
aws codecommit list-repositories --query 'repositories[*].repositoryName' --output text --no-paginate | tr '\t' '\n' | sed 's/$/:/' > repositories_list.txt
```
結果をrepositories_list.txtに出力しています。

全リポジトリを取得するには、--output textオプションが必要とのこと。

## 保存形式は以下の形式になります。
```
cat repositories_list.txt 
A:
B:
C:
```
VBAでExcelシートデータをSQLで取得する方法

# はじめに
　Excelのシート範囲を指定して、その中のデータをSQLを使って取得する方法を知ったので備忘録として載せます。

# サンプルコード
下記はExcelシートでSQLを使用して値を取得し、別シートにデータを出力するサンプルコードです。

```vb
Sub GetExcelDataWithSQL_1()
    Dim cn As Object
    Dim rs As Object
    Dim strSQL As String
    Dim strConnection As String
    Dim ws As Worksheet

    ' ADO Connectionオブジェクトを作成
    Set cn = CreateObject("ADODB.Connection")
    
    ' 接続文字列を設定
    strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=""Excel 12.0;HDR=Yes;IMEX=1"";"
    
    ' 接続を開く
    cn.Open strConnection
    
    ' SQLクエリの作成
    strSQL = "SELECT * FROM [取得$A1:C10]"  ' シート名と範囲を指定
    
    ' ADO Recordsetオブジェクトを作成してSQLクエリを実行
    Set rs = CreateObject("ADODB.Recordset")
    rs.Open strSQL, cn, 1, 1 ' CursorTypeとLockTypeを指定（1=adOpenKeyset, 1=adLockReadOnly）

    ' 結果をシートに出力
    Set ws = ThisWorkbook.Sheets.Add
    ws.Name = "SQL Results１"
    ws.Cells(1, 1).CopyFromRecordset rs

    ' クリーンアップ
    rs.Close
    cn.Close
    Set rs = Nothing
    Set cn = Nothing
End Sub

```

### 解説
- 接続文字列
　通常のSQLと同じで、下記の文字列を使い、接続したいExcelファイルを指定します。
```vb
' 接続文字列を設定
    strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=""Excel 12.0;HDR=Yes;IMEX=1"";"
```

- SQL文
 下記のSQL文で通常と違うのが、テーブル名が"[シート名$データ範囲]"となっており、この範囲がDBで言うテーブルの部分になります。
```vb
' SQLクエリの作成
    strSQL = "SELECT * FROM [取得$A1:C10]"  ' シート名と範囲を指定
```

あとは通常のDB操作と同じ要領でRecordsetオブジェクトに値を受け取り、出力などの操作後、接続を閉じるだけです。
Serverless FrameworkのデプロイがAccesDeniedになる時、チェックする点

sls deployを実行するとき、AccessDeniedでつまづく現象をしばしば目撃していたのでチェックするべき点をまとめました。
デプロイに必要なアクションはSls公式に載っているので割愛。

1.Deploymentbucketの名称は適切か
→たまにタイポがあったりする

2.バケットポリシー、IAMロールの権限は適切か
→IAMロールだけでなくS3バケットポリシーの設定も必要。

3.slsコマンドを実行したマシンのロールは適切か
→ローカルならデフォルトのロール、ECSやCode Build等のコンテナならアタッチされたロールに関連したポリシーがついていることを確認する

4.デプロイ先のバケットでKMSキーを使っている場合、キーポリシーは適切か
→デプロイにもキーポリシーが必要


他に思いついたら書き足していく
【デザインパターンの勉強記録 # 1】 Facadeパターン

# この記事について
デザインパターンについて勉強したアウトプット記事です。
記事の内容で、おかしな点や間違った利用をしている場合、お手数ですがコメントにてご指摘ください！

# 参考にしたリンク

https://qiita.com/Cova8bitdot/items/bdf0976bdfa83e57f121

https://www.slideshare.net/slideshow/unityzenject/82769092

# Facadeパターンとは
Facade(ファサード)パターンについて簡潔に説明をすると、複雑な処理を簡単に利用できる窓口を用意して、利用してもらう考え方です。複雑な処理を窓口にすることによって、利用者には内部処理を隠蔽した状態で利用させることができます。

# 実装したソースコード

https://github.com/hamster3156/FacadePatternSourceCode

<details><summary>ソースコード</summary>
今回、PlayerControllerがファサードクラス(PlayerDateProvider)を利用しています。

```C#
using UnityEngine;

// プレイヤーの動作を制御しているクラス
public class PlayerController : MonoBehaviour
{
    [SerializeField]
    private PlayDataProvider dateProvider;

    private void Update()
    {
        dateProvider.UpdateInput();
        dateProvider.UpdatePosition();
    }
}
```

窓口の役割をしているファサードクラスでは、プレイヤーの入力処理の更新や座標移動処理などの内部処理を実装しています。

```C#
using UnityEngine;

// 窓口の役割を行っているクラス
public class PlayDataProvider : MonoBehaviour
{
    public Vector2 MoveDir => inputManager.MoveInputDir;
    private PlayerInputManager inputManager;
    private PlayerPositionManager positionManager;

    public void UpdateInput()
    {
        inputManager.UpdateInput();
    }

    public void UpdatePosition()
    {
        positionManager.UpdateMovePos(inputManager.MoveInputDir);
    }

    private void Start()
    {
        inputManager = new();
        positionManager = new();
    }
}
```

ファサードクラスで利用されているサブシステム(内部処理)のクラス

```C#
using UnityEngine;

// プレイヤーの入力を管理しているクラス
public class PlayerInputManager
{
    public Vector2 MoveInputDir { get; private set; }

    public void UpdateInput()
    {
        var moveInputDir = new Vector2(Input.GetAxis("Horizontal"),
            Input.GetAxis("Vertical"));
        MoveInputDir = moveInputDir;
    }
}
```

```C#
using UnityEngine;

// プレイヤーの座標を管理しているクラス
public class PlayerPositionManager
{
    public void UpdateMovePos(Vector2 moveDir)
    {
        if (moveDir != Vector2.zero)
        {
            Debug.Log("プレイヤーが移動している");
        }
        else
        {
            Debug.Log("プレイヤーが止まっている");
        }
    }
}
```
</details>

# メリット
- 複雑な処理をまとめる
ファサードクラスを利用するクラスではメソッドだけを実行しているので、具体的な処理を知らない状態でメソッドを利用できる利点があります。
- パラメーター参照に利用する
今回は入力と移動処理で実装を行いましたが、プレイヤーのパラメーターを別々のクラスで管理している場合、パラメーターを参照する窓口として利用することが出来ます。

# デメリット
- 関係ない処理や値を利用できる危険性がある
例えばですが、プレイヤーの処理や値を沢山詰め込んで実装を行った時に、ファサードクラスを参照するだけで、プレイヤーの動作を、関係のないクラスから実行できる危険性があります。

※ 今回、自分が利用して感じたデメリットを記述しています。

# どんな時に使うべきか
個人的には、以下の状況に利用しても良いなと感じました。
- 複雑な処理を簡単に利用したい時
- 参照しないといけないクラスが沢山ある時
- 短期開発
LMDBでnosyncすると速くなった

## 背景
Kontur Population PMTiles ([optgeo/kpop-pmtiles](https://github.com/optgeo/kpop-pmtiles))というプロダクトを作りにあたって、[H3](https://h3geo.org/#)のresolutionを変えながらデータベースに値を記録していくということを行いました。

## わかったこと
[過去の経験](https://qiita.com/hfu/items/a23d8e5168d710490f5b)から、LMDBを使っていたのですが、LMDB.newする際に `:nosync => true` を付加すると高速になることがわかりました。

```ruby
require 'lmdb'

$env = LMDB.new('db', 
  :nosync => true, :nometasync => true, 
  :writemap => true, :mapasync => true, 
  :mapsize => 5000 * 1024 * 1024 * 1024
)
$db = $env.database
```

データベースファイルは　USB 接続された HDD に作成していたのですが、nosync を true にする前には　300 records/s くらいだったところ、nosync を true にした後は 3000 records/s を超える速度を出せていたようです。

## 関係ファイル
https://github.com/optgeo/kpop-pmtiles/blob/main/create_db.rb
link_toメソッドで生成されるアイコンや文字にスタイルを適用する

## 初めに

疑問に思ったことや上手くいかなかったことのアウトプットをしています。
自分なりの理解でアウトプットしていきます。初学者なので誤りもあると思います。
その際はご指摘いただけると幸いです。

## 書き方
```
<%= link_to "sample", xxx_path, id: id番号 %>
```
このようにID属性を作成することでCSSやjavascriptのスタイルを適用できる。

## どうしてidの番号を指定するのか
番号を指定しない場合、一覧など複数のボードがある時、複数のボードに同じIDが適用されることになるため。
原則、HTMLではIDはユニークであるべき。
Java Collectionで使えるメソッドについて

Collectionインターフェイス、およびそのサブインターフェイス、サブクラスで利用できるメソッド、要素の追加、削除ができるメソッドについて整理してみました。


# Collection インターフェイス
## 挿入
### `boolean add(E e)`
指定された要素 e をコレクションに追加します。成功した場合は true を返します。


### `boolean addAll​(Collection<? extends E> c)`
指定されたコレクション c のすべての要素をこのコレクションに追加します。
少なくとも 1 つの要素が追加された場合は true を返します。

## 削除
### `void clear()`
コレクションからすべての要素を削除します。空のコレクションになります。

### `boolean remove(Object o)`
指定された要素 o をこのコレクションから削除します。存在し、削除された場合は true を返します。
注意点として、要素のインデックスではなく、要素の値そのものを引数に指定する必要があります。
削除する要素が既にわかっている状態での使用が前提なので、削除できたかどうか、つまり戻り値はtrueかfalseでいいということだと思います。

### `default boolean removeIf​(Predicate<? super E> filter)`
指定された述語を満たすこのコレクションの要素をすべて削除します。

### `boolean removeAll(Collection<?> c)`
指定されたコレクション c に含まれる要素をこのコレクションからすべて削除します。少なくとも 1 つの要素が削除された場合は true を返します。

### `boolean retainAll(Collection<?> c)`
指定されたコレクション c に含まれる要素以外のすべての要素をこのコレクションから削除します
少なくとも 1 つの要素が削除された場合は true を返します。


# List インターフェイス

## 挿入
### `void add​(int index, E element)`
リスト内の指定された位置に、指定された要素を挿入します。
その位置とそれ以降に要素があればそれらを右に移動させ、各要素のインデックスに1を加えます。

### `boolean addAll​(int index, Collection<? extends E> c)`
指定されたコレクション内のすべての要素を、このリストの指定された位置に挿入します。 その位置とそれ以降に要素がある場合は、それらを右に移動して、各要素のインデックスに1を加えます。 
新しい要素は、指定されたコレクションのイテレータによって返される順序でこのリストに挿入されます。 オペレーションの進行中に、指定されたコレクションが変更された場合の、このオペレーションの動作は定義されていません。

## 削除・取得
### `E remove​(int index)`
List インターフェイスで追加されたメソッドで、指定されたインデックス index の要素を削除し、その要素を返します。 後続の要素を左に移動します(インデックスから1を減算)。
引数にインデックスを指定する、つまり削除する要素が不明でも利用できるメソッドになるので、戻り値として、要素を返すのだと思います。
Collection インターフェイスでもメソッド名は同じremoveが定義されていますが、戻り値はbooleanなので全く別のメソッドです。

### `E get(int index)`
このリスト内の指定された位置にある要素を返します。


## 置換
### `E set​(int index, E element)`
リスト内の指定された位置にある要素を、指定された要素に置き換えます

### `default void replaceAll​(UnaryOperator<E> operator)`
このリストの各要素を、その要素に演算子を適用した結果で置換します。 
演算子によってスローされたエラーまたは実行時例外は、呼出し側に中継されます。
このリストのリスト・イテレータがset操作をサポートしない場合、最初の要素を置き換えるときにUnsupportedOperationExceptionがスローされます。

### `default void sort​(Comparator<? super E> c)`
指定されたComparatorが示す順序に従って、このリストをソートします。
指定されたコンパレータがnullの場合は、リストの全要素でComparableインタフェースを実装し、要素の自然順序を使用する必要があります。

# Queue インターフェイス
## 挿入
### `boolean offer​(E e)`
容量制限に違反せずにすぐ実行できる場合は、指定された要素をこのキューに挿入します。 
容量制限のあるキューを使用する場合、通常は、要素の挿入に失敗した場合に例外をスローするだけのadd(E)よりもこのメソッドを使用することをお薦めします。

## 取得・削除
### `E element()`
キューの先頭を取得しますが、削除しません。 このメソッドは、キューが空の場合に例外をスローする点のみがpeekメソッドと異なります。

### `E peek()`
キューの先頭を取得しますが、削除しません。キューが空の場合はnullを返します。

### `E remove()`
キューの先頭を取得および削除します。 
このメソッドは、キューが空の場合に例外をスローする点のみがpoll()メソッドと異なります。

### `E poll()`
キューの先頭を取得および削除します。キューが空の場合はnullを返します。

# Document
:::note
[`Collection`](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/Collection.htm)
[`List`](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/List.html)
[`Queue`](https://docs.oracle.com/javase/jp/11/docs/api/java.base/java/util/Queue.html)
:::


https://qiita.com/T-ngtj/private/df254aacd05be698199a
SetMaterialの秘密

自分へのメモを兼ねてQitaに残しておきます。
今回の話は、秘密でも何でもなく、知っている人は既に知っていると思いますが、長年さわっていて、改めて気づいた事を書きます。



# 調査環境

UnrealEngine 5.3.2

# SetMaterialとは

この記事では以下のノードを指します。

![SetMaterialノード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/052e04d5-0772-9cea-dca9-4992b96bf624.png)

使用頻度も高いと思われ、『スタティックメッシュ』『スケルタルメッシュ』『ジオメトリキャッシュ』『フォリッジ』等のモデルアセットのマテリアルをブループリントから変更できるノードです。

# 気づいた事

ここからが本題で結論になります。
このSetMaterialノードの**引数の三つ目**は、変更するマテリアルを設定して実行します。もし、『**何もマテリアルを設定せず**』に実行するとどうなるのでしょうか？
答えは、**各メッシュデータのアセットに設定されているメッシュがセット**されます。


ここで実験してみました。
このレベルは、椅子(スタティックメッシュ)、車(スケルタルメッシュ)、フォリッジ(スタティックメッシュフォリッジ)となっています。

![元レベル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/90068a65-4a4a-fff6-9eca-b27fd5c2da84.png)

それぞれ、『**SetMaterialで赤いマテリアルに変更**』にしてみました。

**スタティックメッシュを変更**

![スタティックメッシュだけ変更.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/cd188f20-42ae-2109-aee1-29c6049e94cd.png)

**スケルタルメッシュを変更**

![スケルタルメッシュだけ変更.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/c7535dee-d579-91d0-ea0d-0567ba05d744.png)

**フォリッジを変更**

![Foliageだけ変更.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/62dbb6e4-b8c3-4f60-7ba7-5225f27466f4.png)

その後、『SetMaterialに何もマテリアルを指さず実行』したものが次の画像です。

![元レベル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/90068a65-4a4a-fff6-9eca-b27fd5c2da84.png)

このようにアセットに設定されているマテリアルが貼り張り直されます。
少なくとも、『スタティックメッシュ』『スケルタルメッシュ』『スタティックメッシュフォリッジ』では元のマテリアルがセットされています。

# 最後に

先入観で、『DefaultMaterial(アクタを配置して最初に貼られているグレーのマテリアル)が貼られる』か『実行に失敗する』かだろうと思っていましたが、実際の動作は違いました。
今までは、わざわざ、元のマテリアルをキープしておいて、変更とかやっていましたが、そんな事しなくても良かったのですね。今後のブループリントに作り方もすっきりしそうです！
JavaScript組み込みオブジェクト  文字列、日付

## 文字列オブジェクト
文字列はコンストラクタを使用しなくてもインスタンスを生成できる
```JavaScript
let animal=new String("くま");//①
let animal="くま";//①をこのように省略可能
```
```JavaScript
console.log(animal.lengh);
2
```

## 文字列を検索するメソッド
Stringが検索文字を含む場合はtrue、
含まない場合はfalseを返す。
```JavaScript
String.includes(検索文字列[,検索開始位置デフォ0]);
```
検索文字が先頭から何文字目に見つかったかを返す。
見つからなかったら-1を返す。
```JavaScript
String.indexOf(検索文字列[,検索開始位置デフォ0]);
```

## 文字列を分割するメソッド
文字列の一部取り出し、分割して配列にできる。

引数で指定した範囲の文字列をStringから取り出した後、
新しい文字列を返す。
終了位置を省略したら最後まで指定ということ。
開始位置は0から、終了位置は1から始まる。

```JavaScript
String.slice(取り出し開始位置[,終了位置]);
```
```JavaScript
let animalpic="bear.png";
let lastIndex=animalpic.indexOf("."); //.が何文字目にあるか

console.log(animalpic.slice(0,lastIndex)); //0文字目から.の前まで抜き出す
bear
```

分割した１つ１つを要素とする配列を返す。
最大値を指定したらそれ以上は切り捨て
区切り文字を省略したら空文字を指定したとみなす。
```JavaScript
String.split([区切り文字[,分割最大数]]);
```
```JavaScript
let animal="bear.cat.dog";
let animals=animal.split("."); //.で区切って配列に
console.log(animals{0});
bear
```

## 配列オブジェクト
```JavaScript
let coin =[1,5,10,50];
console.log(coin.length);
4
```

## 配列を文字列として返すメソッド
配列のすべての要素を区切り文字でつないで返す。省略した場合は","が区切り文字となる。
```JavaScript
Array.join([区切り文字]);
```
```JavaScript
let animals=["bear","cat","dog"];
console.log(animals.join("!"));
bear!cat!dog!
```

## 配列要素を追加・削除するメソッド
指定した要素を配列の最後に追加
追加後の配列の要素数を返す
```JavaScript
Array.push(追加要素1[,追加要素2]);
```
```JavaScript
let coin=[1,5,10];//配列の宣言
console.log(coin.push(50,100));//最後に50,100を追加
5//追加後の要素数が出力

console.log(coin[4]);//確認で配列の要素番号4番目を出力
100
```

配列の最後の要素を取り出す
取り出された最後の要素は配列から削除される
```JavaScript
Array.pop();
```

指定した要素を配列の最初に追加
追加後の配列の要素数を返す
```JavaScript
Array.unshift(追加要素1[,追加要素2]);
```

配列の最初の要素を取り出す
取り出された最初の要素は配列から削除される
```JavaScript
Array.shift();
```

## 日付オブジェクト
コンストラクタに日付を指定してインスタンスを生成する。
月をカンマ区切りで数値として指定するときは0始まりになる。(ex.1月→0)
```JavaScript
naw Date();//現在の時刻
```
```JavaScript
new Date("2024-1-1");//2024年1月1日0時0分0秒
```
```JavaScript
new Date("2024,0,1");//2024年1月1日0時0分0秒
```
```JavaScript
new Date("2024,0,1,12,2,31");//2024年1月1日12時2分31秒
```

## 日付を取得するメソッド
月と曜日は0始まりになる点に注意する
・1月：0、2月：1、、、
・日曜日：0、月曜日：1、、、

```JavaScript
let now=new Date();//2024年8月19日18時35分34秒

console.log(now.getFullYear);//2024年
2024

console.log(now.getMonth);//8月
7

console.log(now.getDay);//月曜日
1
```
```JavaScript
getFullYear();//年
getMonth();//月
getDate();//日
getDay();//曜日
getHours();//時間
getMinutes();//分
getSeconds();//秒
getMilliseconds();//ミリ秒
```

## 日付を設定するメソッド
```JavaScript
let now=new Date();//2024年8月19日18時35分34秒

now.setFullYear(now.getFullYear()+5);//現在の日時の5年後を設定

console.log(now.getFullYear());
2029
```

・xに引数を指定する
・曜日はsetメソッドがない
```JavaScript
setFullYear(x);//年
setMonth(x);//月
setDate(x);//日
setHours(x);//時間
setMinutes(x);//分
setSeconds(x);//秒
setMilliseconds(x);//ミリ秒
```

## 日付型を文字列にするメソッド
```JavaScript
Date.toLocaleString()//年/月/日 時:分:秒
Date.toLocaleDateString()//年/月/日
Date.toLocaleTimeString()//時:分:秒
```

```JavaScript
let now=new Date();//2024年8月19日18時35分34秒

console.log(now.toLocaleString());
2024/8/19 18:35:34

console.log(now.toLocaleDateString());
2024/8/19

console.log(now.toLocaleTimeString());
18:35:34
```
Terraformコマンド一覧

## Terraformについて
https://qiita.com/JK447/items/e0cddf956cd9d333febb




![napkin-selection (16).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3690843/43914159-8cae-fc75-479b-845ac16d6835.png)

## コマンド一覧

| コマンド | 説明 | 使用例 |
|----------|------|--------|
| terraform init | プロジェクトを初期化し、必要なプラグインをダウンロード | `terraform init` |
| terraform plan | 実行プランを作成し、リソースの変更を確認 | `terraform plan` |
| terraform apply | 計画に基づいてリソースを作成・変更・削除 | `terraform apply` |
| terraform destroy | 管理しているリソースを削除 | `terraform destroy` |
| terraform show | 現在の状態ファイルを表示 | `terraform show` |
| terraform output | 出力変数の値を表示 | `terraform output` |
| terraform fmt | 設定ファイルを標準的な形式にフォーマット | `terraform fmt` |
| terraform validate | 設定ファイルの構文を検証 | `terraform validate` |
| terraform taint | 特定のリソースを強制的に再作成対象にマーク | `terraform taint aws_instance.example` |
| terraform untaint | taintされたリソースのマークを解除 | `terraform untaint aws_instance.example` |
| terraform state | 状態ファイルを管理するためのコマンド | `terraform state list` |
| terraform state list | 状態ファイルに保存されているリソースのリストを表示 | `terraform state list` |
| terraform state show | 特定のリソースの状態を表示 | `terraform state show aws_instance.example` |
| terraform state mv | リソースを状態ファイル内で移動 | `terraform state mv aws_instance.example aws_instance.new_example` |
| terraform state rm | 状態ファイルからリソースを削除 | `terraform state rm aws_instance.example` |
| terraform import | 既存のインフラストラクチャをTerraformの管理下にインポート | `terraform import aws_instance.example i-1234567890abcdef0` |
| terraform refresh | 実際のインフラストラクチャの状態と状態ファイルを同期 | `terraform refresh` |
| terraform graph | リソースの依存関係をグラフで表示 | `terraform graph` |
| terraform workspace | 複数の環境を管理するためのワークスペース管理 | `terraform workspace new dev` |
| terraform workspace list | ワークスペースのリストを表示 | `terraform workspace list` |
| terraform workspace select | 既存のワークスペースを選択 | `terraform workspace select dev` |
| terraform workspace delete | ワークスペースを削除 | `terraform workspace delete dev` |
| terraform get | モジュールをダウンロード | `terraform get` |
| terraform module list | プロジェクト内のモジュールのリストを表示 | `terraform module list` |
| terraform version | 現在のTerraformのバージョンを表示 | `terraform version` |


# 【参考】
https://developer.hashicorp.com/terraform/docs
JavaScriptの基礎 関数

## 関数の定義
```JavaScript
function animal(){
    console.log("bear");
};
```
呼び出し
```JavaScript
animal();
bear
```
こう書くこともできる
```JavaScript
const animal=function(){
    console.log("bear");
}
animal();
```


## 関数に引数を受け取る変数を指定
```JavaScript
function animal(doubutu){
    console.log(doubutu);
};
```
引数catを持たせて呼び出し
```JavaScript
animal("cat");
cat
```

## 引数は複数渡すこともできる
```JavaScript
function animal(doubutu,name){
    let animalname=doubutu+":"+name
    console.log(animalname);
};
```
引数を持たせて呼び出し
```JavaScript
animal("cat","ミケ");
cat:ミケ
```


## 引数として配列を渡すこともできる
```JavaScript
function sumCard(card){
    let total=0;
    for(let i=0;i<card.length;i++){
        total=total+card[i];
    }
    console.log(total);
}
```
呼び出し側
```JavaScript
let myCard =[1,2,3];
sumCard(myCard);
```
JavaScriptの基礎と配列

## JavaScriptの基礎
```
let //変数
const //定数
```
```
&& //AND
|| //OR
```
```
コメント // /* */
```

## ==と===の違い

==：等値演算子
左右の値が同じ場合にtrue
型変換はJavaScript側で自動的に行う
!=：不等演算子

===：同値演算子
値と型が同じ場合にtrue
!==：非同値演算子

## 配列の宣言
```JavaScript
let 変数名=[];
let 変数名=[値１,値２];
```
要素番号は0から数える
```JavaScript
let id=[1,2,3]
let names=[佐藤,伊藤,田中]

console.log(id[0]);
1
```

プリミティブ型であるnameとnamesの箱は別なのでnameの中身を変えても配列の値は連動しない。
※オブジェクト型の場合は、代入元と代入先の変数が共有される。
```JavaScript
let name=names[1];
//nameに伊藤が代入

name="高橋";
//nameに高橋を再代入

console.log(name);
高橋

console.log(names[1]);
伊藤
```


## 連想配列
・配列の要素１つ１つに鍵のような任意の番号を振ることができる。
・鍵には""をつける必要がある。
・name[100]の場合101番目の要素を取り出すということになる。

100という鍵付きの箱に佐藤をいれる
```JavaScript
let name={
    100:"佐藤",
    200:"伊藤",
    300:"田中"
};
```

取り出すとき
```JavaScript
consoe.log(name["100"]);
佐藤
```

## 応用
配列の箱１つ１つに複数の要素をもたせる

・idやnameのようなプロパティ名は配列の宣言時に""で囲む必要はない。
・"kibou busyo"のように空白を含む際は囲む必要がある。
```JavaScript
let names=[
    {id:"100",name:"佐藤"},
    {id:"200",name:"伊藤"},
    {id:"300",name:"田中"}
];
```
names配列の要素番号0番目のidとnameの値を取り出す
```JavaScript
console.log(names[0]["id"]+":"+names[0]["name"]);
100:佐藤
```