OmniAICreator/Qiita-1.07M huggingface dataset:
深さ可変のMLPを見つけて目から鱗だった話

# はじめに

kaggle等でMLPの実装を探すと，kerasのSequentialにDense層やDropout層をaddしまくるような実装をよく見かけます．

torch.nn.Moduleを用いた実装では，Linearと活性化関数を2,3個繰り返す実装が多いように思います．

これらはMLPの概念に忠実な実装です．

しかしMLPの中間層の数を簡単に自由に変更できれば，より柔軟な実装ができるかもしれません．

ここで紹介するアイデアはシンプルで誰でも思いつきそうなものですが，レイヤ数が固定の実装ばかり見ていると考え方が固くなってしまい，筆者にとっては新鮮なものであったので記事にしました．

# Keras (Sequential)

中間層のサイズを指定して，for文でn_layer-2個のDense層とDropout層を追加すれば，可変個数の層を追加できる．

``` py
from keras.models import Sequential
from keras.layers import Dense, Dropout

model = Sequential()

model.add(Dense(hidden_size, activation='relu', input_shape=input_shape))

for _ in range(n_layer-2):
    model.add(Dense(hidden_size, activation='relu'))
    model.add(Dropout(0.2))
    
model.add(Dense(num_classes, activation='softmax'))

model.compile(loss='categorical_crossentropy',
                   optimizer=Adam(),
                  metrics=['accuracy'])
model.fit(x_train, y_train,
          batch_size=batch_size,
          epochs=epochs,
          verbose=2, 
          validation_data=(x_val, y_val))
score = model.evaluate(x_test, y_test, verbose=0)
```

# torch.nn.Module

LinearとBatchNorm1dをforで交互に追加し，ModuleList()に追加する．
ModuleListなんてあったんですね……

forwardでも同じ順番で，活性化関数とdropoutを加えてfor文で回す必要があり，ちょっとめんどくさい．

``` py
import torch
import torch.nn.functional as F

class MLP(torch.nn.Module):
    def __init__(self, in_channels, hidden_channels, out_channels, num_layers, dropout):
        super(MLP, self).__init__()
        # 1st layer
        self.lins = torch.nn.ModuleList()
        self.lins.append(torch.nn.Linear(in_channels, hidden_channels))
        self.bns = torch.nn.ModuleList()
        self.bns.append(torch.nn.BatchNorm1d(hidden_channels))
        
        for _ in range(num_layers - 2):
            self.lins.append(torch.nn.Linear(hidden_channels, hidden_channels))
            self.bns.append(torch.nn.BatchNorm1d(hidden_channels))
        # last layer
        self.lins.append(torch.nn.Linear(hidden_channels, out_channels))

        self.dropout = dropout

    def reset_parameters(self):
        for lin in self.lins:
            lin.reset_parameters()
        for bn in self.bns:
            bn.reset_parameters()

    def forward(self, x):    
        for i in range(num_layers - 1):
            x = self.lins[i](x)
            x = self.bns[i](x)
            x = F.relu(x, inplace=True)
            x = F.dropout(x, p=self.dropout)
        x = self.lins[-1](x)
        return F.log_softmax(x, dim=-1)
```

# さいごに

参考

https://github.com/CUAI/CorrectAndSmooth/
すぐangrで殴れるようになりたい

# はじめに
CTFでreversingをしばらく休んでいた後久しぶりにangrを使おうと思ったら……どうやって書くか忘れていました！

angrをスッと出せるように自分用メモです


参考

https://github.com/angr/angr-examples/tree/master

# 公式のサンプル

https://github.com/angr/angr

分かりやすいように少し改変
``` py
import angr

project = angr.Project("./chall", auto_load_libs=False)

@project.hook(0x400844) # 目標
def print_flag(state):
    print("FLAG SHOULD BE:", state.posix.dumps(0))
    project.terminate_execution()

project.execute()
```

# ちゃんと書く

Ghidraで見て，"Correct!" "Incorrect."とでも表示されるような場合．

``` py
import angr

proj = angr.Project("chall", auto_load_libs=False)
print("ARCH", proj.arch)
print("EntryPoint", proj.entry)
print("FileName", proj.filename)

state = proj.factory.entry_state()
# state = proj.factory.entry_state(args=["./chall", argv])
simgr = proj.factory.simgr(state)
simgr.active

print(proj.loader)
print(proj.loader.min_addr)

simgr.explore(find=(0x400000 + 0x1234), avoid=(0x400000 + 0x1256))

simgr.found[0].posix.dumps(0)
```
avoidにはリストを指定することも可能

# 細かい指定など
## コマンドライン引数で指定

コマンドライン引数でFLAGを入力するような場合，BVSで入力ビット数を指定した変数を用意し，argsに追加する．

``` py
import claripy

argv1 = claripy.BVS("argv1", input_size * 8)

state = proj.factory.entry_state(args=["./chall", argv1], add_options={angr.options.LAZY_SOLVES})

```

## 文字列を制限

add_constraintsで条件を追加できる．
`.chop(8)`は1バイトずつ，の意．

``` py
# not null
for byte in argv1.chop(8):
    state.add_constraints(byte != '\x00')

# format is FLAG{...}
state.add_constraints(argv1.chop(8)[0] == 'F')
state.add_constraints(argv1.chop(8)[1] == 'L')
state.add_constraints(argv1.chop(8)[2] == 'A')
state.add_constraints(argv1.chop(8)[3] == 'G')
state.add_constraints(argv1.chop(8)[4] == '{')
```

## 標準入力

``` py
flag = claripy.BVS('flag', flag_size*8)
state = proj.factory.blank_state(addr=START, stdin=flag)
```

## 手動でメモリに変数を設定

``` py
state.memory.store(address, state.solver.BVV("ans", 32*8))
```

# さいご

https://github.com/angr/angr-examples/tree/master

ここのコード見て勉強すれば大体のangrの使い方が分かります
ghq+pecoでリポジトリ管理

# はじめに
リポジトリが増えたせいで、リポジトリ間の移動に手間がかかってしまった場合や、リポジトリの位置がバラバラになって管理が難しくなった場合はありませんか？
僕は`ghq`については、すでに知って使っていましたが、最近`peco`を組み合わせて使ってみた結果、より便利になったと思いました。
そのため、今回はghqとpecoを使ったリポジトリの管理について紹介してみたいと思います。

ghqとpecoのインストール方法は色々ありますが、`brew`を使ってインストールすることが可能です。
`brew`のインストールしたい場合は、以下の記事を参考してください。

https://qiita.com/dev-cho/items/7a75e3852c4074a7db63

# ghq
https://github.com/x-motemen/ghq

ghqは、リポジトリのURLを使って、特定のルートディレクトリの下にディレクトリをクローンするリポジトリ管理ツールです。

`brew`を使ってツールをインストールする場合は、以下のコマンドを実行します。
```console
$ brew install ghq
```
リポジトリが増えても特定のルートディレクトリの下にリポジトリが整理されるので、リポジトリの管理がしやすくなります。
例として、以下のようなコマンドを使って、リポジトリをクローンしたり、リポジトリの一覧確認ができます。
```console
# git cloneの代わりに、リポジトリをghqのディレクトリにクローンします。
$ ghq get https://github.com/foo/bar.git
```
```console
# ghqのルートディレクトリの下にあるリポジトリの一覧を表示します。
$ ghq list
```


# peco
https://github.com/peco/peco

CLI上でリスト表示されるものに対して、入力した情報から行を絞り込んで表示するツールです。
他のコマンドと組み合わせると便利なものになります。

`brew`を使ってツールをインストールする場合は、以下のコマンドを実行します。
```console
$ brew install peco
```

# ghqとpecoを組み合わせる

僕は例のように`.bashrc`にghqのリポジトリのパスをpecoを使って表示し、行を選択することで該当するリポジトリに移動するエイリアスを設定しました。

```shell:.bashrc
alias cdghq='cd $(ghq root)/$(ghq list | peco)'
```

設定した上記のコマンドを実行すると以下の例のように表示されます。
その表示からリポジトリの検索や移動ができます。
```console
QUERY>                                     IgnoreCase [2 (1/1)]
github.com/foo/bar
github.com/baz/qux
```

# おわりに
ghqとpecoを使うことで

- 特定のディレクトリの下にリポジトリがクローンされるので、他のディレクトリがきれいになる
- 特定のディレクトリの下にリポジトリが整理されるので、リポジトリの管理がしやすくなる
- リポジトリ間の移動が簡単になる

などの理由で、効率よくリポジトリ管理や作業ができると思います。
requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0)というエラー

# はじめに
　前回に引き続き、FastAPIを用いた会議室予約アプリの作成中に出てきたエラー文です。
 
# 問題
 ```
raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
```
上記のエラーに遭遇。
# 原因
API側から受け取ったデータが変である可能性ありとのこと。
https://teratail.com/questions/tm5eg39ug7j7uy

```
#main.py
@app.get("/bookings", response_model=List[schemas.Booking])
async def read_bookings(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
    booking = crud.get_bookings(db, skip=skip, limit=limit)
    return bookings

#app.py
url_bookings = 'http://127.0.0.1:8000/bookings'
    res = requests.get(url_bookings)
    bookings = res.json()
    df_bookings = pd.DataFrame(bookings)
```
main.pyを確認したら,「booking」という変数に対して「return bookings」となっている。

# 解決
このコードではbookingsという変数は空のデータとなっているため、こちらのエラーが出ていた。
booking→bookingsと修正、エラーは解消された。
ただのタイプミス、、、

# 終わりに
今のところエラーは９割タイプミス。どんなエラーもまずはタイプミスを疑う必要があるのですね。
いまさらdockerを始めてみる⑤

# 前回
whts is nextのwhat is docker composeとunderstanding image layersを学んだ。yamlファイルを使って複数のdockerをまとめてrun(compose)するのと、imageにlayerを追加する操作を体感した

# Writing a DockerFile
A Dockerfiles is a text-based document that's used to a crate a container iamge
imageをつくるための設計図みたいなもんかな

sample
```
FROM python:3.12
WORDIR /usr/local/app
COPY requirements.txt ./
RUN pip install --nocache-dir -r requirements.txt
COPY src ./src
EXPOSE 5000
RUN useadd app
USER app
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080"]
```

一行目から
- FROM <image>: specifies tha base image
- WORDDIR <Path>: specifies the working directory or the path in tha image where files be copied and commands will be execited
- COPY <host-path> <image-path>: tells builder to copy files from the host and put them into the continer image
- RUN <command>: tells builders to run the specified command
- EXPOSE <port-number>: sets configuration on the image that indicates a port the image would like to expose
- USER <user-or-uid>: sets the default user for all subsequent instructions
- CMD ["<command>" , "<arg>"]: sets the default command a conteiner using this image will run

tyr it out
デスクトップにtestディレクトリを作成。
中身はDockerfileだけ![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269297/24cf8709-5f1e-1d78-6168-8fab05e7473c.png)


```Dockerfile
FROM node:20-alpine
WORKDIR /usr/local/app
COPY . .
RUN yarn install --production
CMD ["node", "./src/index.js"]
```

DockerDesktopを起動
→コマンドプロンプトを起動&cd
→```docker container build -t myimage .```

なんかできた
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269297/51eea2a7-1a70-7aab-204c-03138d083a26.png)

GUIのimageのところに追加されている。conteinerの作成まではしてないみたい
![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269297/c682d526-f435-b7c2-eeea-d5fe63b58f94.png)

コマンド実行後もディレクトリにファイルは追加されていない。プロジェクトを作るようなコマンドではないってことかな


# Build, tag, and publish an image
Build: the process of building an image based on a Dockerfile
Tagging: the process of giving an image a name, which also detemines where the image can be distributed

tagのformat
```[HOST[:PORT_NUMBER]/]PATH[:TAG]
```
例
- docker.io/library/nginx:latest: pulls an image from the docker.io registry, the library namespace, the nginx image repository and the latest tag
- ghcr.io/dockersamples/example-voting-app-vote:pr-311: pulls an image from the GitHub Container Registry, the dockersamples namespace, the example-voting-app-vote iamge repository, and the pr-311 tag
-

tagを使うと簡単にimage引っ張ってこれますよってこと？よくわからん。try it outは上でやったのとほぼ同じだから省略。

今日は内容すくないけどここまで。
ドべ初心者のREST API 設計理解

## ゴール
- POST、PUTの違いがわかる人間になる
- endpoint、header、bodyに何を持たせて何を持たせないかがわかる人間になる

## これがお手本だ！！ (by ChatGPT出力)

~もしユーザー情報関連のAPIを作るとしたら~

```
// ユーザー情報取得API

Method: GET
Endpoint: /users/{userId}
Header:
    Authorization: Bearer {token}
    Accept: application/json
Body: なし（GETメソッドでは通常使用しない）
```
```
// ユーザー情報更新API

Method: PUT または PATCH
Endpoint: /users/{userId}
Header:
    Authorization: Bearer {token}
    Content-Type: application/json
Body:
    {
      "name": "新しい名前",
      "email": "newemail@example.com"
    }
```
```
// ユーザー情報削除API

Method: DELETE
Endpoint: /users/{userId}
Header:
    Authorization: Bearer {token}
    Body: なし（DELETEメソッドでは通常使用しない）
```

## 各パラメータの違い

#### POST、PUTの違い
新規登録 は POST、
更新 は PUT
というだけのことです。

#### endpoint、header、bodyの違い（それぞれ何を持たせるか）

- endpoint
    - リソースを**特定する内容**を含む
    - 例えば、ユーザー関連APIの場合はユーザーを特定できる情報＝user_idをエンドポイントに含める、など
    - 例：ユーザーID、商品ID、識別ID系のもの

- header
    - APIリクエスト/レスポンスと共に送られる**メタデータ**が含まれる
    - 例：
        - 認証情報（トークン等）
        - コンテンツの種類（Content-Type）
        - 許可されているリクエスト方法（メソッド）やオリジン（CORS設定）
        - キャッシュポリシー

- body
    - **実際にサーバーに送信されるデータ**が含まれる
    - 例：
        - ユーザーの作成や更新時に必要な情報（例: 名前、メールアドレス）
    - GET、DELETEメソッドの場合はbodyを使用しないことが多い


## 補足

**エンドポイントは具体的すぎる情報を避ける。**

例えば、

【ダメな例】
ユーザー**取得**API（**GET**メソッド）：/v1/user/**get_user**/{user_id}
ユーザー**更新**API（**PUT**メソッド）：/v1/user/**update_user**/{user_id}

【良い例】
ユーザー**取得**API（**GET**メソッド）：/v1/**user**/{user_id}
ユーザー**更新**API（**PUT**メソッド）：/v1/**user**/{user_id}

取得、更新はメソッド（GET、PUT）で区別できるから、どっちも同じエンドポイントの方がシンプルでいいよね、という話らしいです。
AtCoder Beginner Contest 358 をJavaで解けるところまで

## 概要
AtCoder主催のAtCoder Beginner Contest 358が、
2024年6月15日(土)21時から開催されました。
私は失念しており不参加です。

解説なし、時間無制限で解けるところまでやってみます。

## A
```Java
import java.util.Scanner;

public class Main {

  public static void main(String[] args) {
    var sc = new Scanner(System.in);
    String S = sc.next(), T = sc.next();
    if(S.equals("AtCoder") && T.equals("Land")) {
      System.out.println("Yes");
    } else {
      System.out.println("No");
    }
  }
}
```
文字列が２つ入力されるので、比較する。

## B
```Java
import java.util.Scanner;

public class Main {

  public static void main(String[] args) {
    var sc = new Scanner(System.in);
    int N = sc.nextInt();
    int A = sc.nextInt();
    int[] T = new int[N];
    for (int i = 0; i < N; i++) {
      T[i] = sc.nextInt();
    }

    int tmp = 0;
    for (int i : T) {
      if (i > tmp) {
        tmp = i;
      }
      tmp += A;
      System.out.println(tmp);
    }
  }
}
```
B問題にしてはちょっと悩みました。
Ti(入場者がチケット売り場に来た時間)と
1つ前の入場者がチケットを受け取る時間を比較して時間が長い方に、
A(チケット購入手続き時間)を足せばよい。

## C
```Java
import java.util.Arrays;
import java.util.Scanner;

public class Main {

  public static void main(String[] args) {
    var sc = new Scanner(System.in);

    int N = sc.nextInt(), M = sc.nextInt();

    String[][] s = new String[N][M];
    for (int i = 0; i < N; i++) {
      var S = sc.next().toCharArray();
      for (int j = 0; j < M; j++) {
        s[i][j] = String.valueOf(S[j]);
      }
    }

    // ベースのBoolean配列
    Boolean[] base = new Boolean[M];
    for (int i = 0; i < M; i++) {
      base[i] = false;
    }

    // bit全探索
    int min = 10;
    for (int i = 0; i < 1 << N; i++) {
      Boolean[] check = Arrays.copyOf(base, M);
      int buyCount = 0;
      for (int j = 0; j < N; j++) {
        if ((1 & i >> j) == 1) {
          // 購入店舗数として出力する
          buyCount++;
          // check配列のIndexとして使用する
          int storeNum = 0;
          // 1文字ずつ○×を判定する
          for (String taste : s[j]) {
            if (taste.equals("o")) {
              check[storeNum] = true;
            }
            storeNum++;
          }
        }
      }
      // 全てtrueなら購入店舗数を出力
      if (!Arrays.asList(check).contains(false) && min > buyCount) {
        min = buyCount;
      }
    }
    System.out.println(min);
  }
}
```
問題を読んですぐbit全探索だと思う。
シフト演算子を毎回どうするのか忘れてしまうためググる。

最短で合致する購入店舗数＝最低購入店舗数だと勘違いしていたため、
一度結果がWAを出してしまいました。
Arrays.copyOfなんて初めて使いました。
checkは元々プリミティブ型の配列を考えていましたが、
Arrays.asListのcontainsした時の動作が変わってしまうため急遽参照型に変更。
Arrays.asListはオートボクシングしないという仕様で引っかかっていました。
その結果宣言した際にはcheckの中身が全てfalse→nullに代わってしまったためbaseを宣言。
もっと効率のいいやり方を探すために明日は他の方のJavaの回答を確認します。

## D
私の知っているアルゴリズムでは解けないことだけはわかるため、ここまで。
今後の学習予定としてはDP(動的計画法)が最優先です。
【GCP】ログエクスプローラーで正規表現を使ったフィルタリング

# TL;DR
検索クエリを入れるとき=~とすれば正規表現が使える。
```
key=~".*Qiita\d+"
```

# 本文
以下のような3つのログを出力していたとする。
```json
{
	"apiName": "POST Regist",
	"jsonPayload": {
		"userName": "田中太郎",
		"message": "Message."
	},
	"labels": {
		"version": "1.0.0"
	}
}
```

```json
{
	"apiName": "POST Login",
	"jsonPayload": {
		"userName": "山田花子",
		"message": "Message."
	},
	"labels": {
		"version": "1.0.1"
	}
}
```

```json
{
	"apiName": "GET Info",
	"jsonPayload": {
		"userName": "田中花子",
		"message": "Message."
	},
	"labels": {
		"version": "2.0.0"
	}
}
```

以下の②の部分に正規表現のクエリが書ける。
クエリを実行（Run query）で実行。

https://cloud.google.com/logging/docs/view/logs-explorer-interface?hl=ja#logs-viewer-interface

![スクリーンショット 2024-06-17 23.42.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855584/c3d960d7-69ea-88dc-d5ed-ea14cad039ac.png)

### POSTという文字列を含むログを抽出
```
apiName=~"POST.*"
```

### 名前が花子さんだけ抽出
```
jsonPayload.userName=~".*花子"
```

### versionが1.0.*のログだけ抽出
jsonPayloadのようなGCPで用意されているフィールド以外はkeyを指定して降りていくとき""で括る必要があるっぽい。
入力してるとlabelsの時点で補完してくれるので意識はしなくてもいいと思う。
```
labels."version"=~"^1\.0\.\d+$"
```
【VSCode】OSの設定に合わせて配色テーマを変更する方法

`settings.json` に以下の設定を追加することでOSの設定に合わせて配色テーマが変更されるようになります。

```jsonc:settins.json

{
  "window.autoDetectColorScheme": true,  // OSの設定に合わせて自動で配色テーマが変更されるようにする
  "workbench.preferredDarkColorTheme": "",  // ダークモードの場合に適用される配色テーマ
  "workbench.preferredLightColorTheme": "",  // ライトモードの場合に適用される配色テーマ
}

```
Verseでの位置や向きの扱いについて

# 1.はじめに
この記事を読むと、Verseでのプレイヤーやデバイス、建築小道具の位置や角度の取得方法、設定方法がわかります。それがわかると、デバイス・建築小道具にプレイヤーを追跡させたり、プレイヤーを好きな位置にテレポートさせたりすることができます。

# 2.transform構造体の使い方を知ろう
プレイヤーやデバイス、物体はtransform構造体を持っていて、その中に位置や向きの情報を持っています。なので、transform構造体の中身や使い方を知りましょう。

■これ以降の表記の仕方で1つだけ約束をしておきます。

:::note info
コードブロック内の[クラス名または型名]という表現は
クラス名または型名のインスタンスや変数を表します。
:::
## 1)transform構造体の取得方法
### ①基本的な書き方
```
[fort_characterまたは、XXX_device、creative_prop].GetTransform()
```
### ②サンプルコード
#### プレイヤーの場合
```
# ①agentまたは②playerからfort_characterへの変換
# ①agentの場合
FortChar := [agent].GetFortCharacter[]
# ②playerの場合
FortChar := [player].GetFortCharacter[]

# fort_characterのGetTransformメソッドでtransformを取得
Transform := FortChar.GetTransform()
```

#### デバイス・建築小道具の場合
```
# UEFNからデバイスを設定できるようにする
@editable Button : button_device = button_device{}
# UEFNから建築小道具を設定できるようにする
@editable Prop : creative_prop = creative_prop{}

# GetTransformメソッドでtransformを取得
ButtonTransform := Button.GetTransform()
PropTransform := Prop.GetTransform()
```

## 2)transform構造体メンバー
### ①構造体メンバー
構造体のメンバーは以下のとおりです。（公式サイト　[transform struct](https://dev.epicgames.com/documentation/en-us/uefn/verse-api/unrealenginedotcom/temporary/spatialmath/transform)）

| メンバー名 | 型 | 入っている情報 |
|:-|:-|:-|
|Scale|vector3|スケール|
|Rotation|rotation|回転情報|
|Translation|vector3|位置情報|

### ②各メンバー詳細
### ⅰ)Scale
#### 取得方法
```
Scale := FortChar.GetTransform().Scale
```
#### データの使い方
vector3なのでTranslationと同様に操作可能です。
Translationの説明を参考にしてください。

### ⅱ)Rotation
角度にはYaw,Pitch,Rollがあります。
※Yaw,Pitch,Rollについては以下のページを参考にしてください。
[Wikipedia ローリング](https://ja.wikipedia.org/wiki/%E3%83%AD%E3%83%BC%E3%83%AA%E3%83%B3%E3%82%B0)
#### 取得方法
rotation構造体を取得する方法とrotation構造体から角度を取得する方法です。
※取得できるのは弧度法(radian)ではなく、度数法(degree)の角度になります。
```
# 回転情報（rotation）を取得　※FortCharはfort_characterクラスのインスタンスとします
Rotation := FortChar.GetTransform().Rotation

# Yaw,Pitch,Rollの入った配列を取得
Degrees := Rotation.GetYawPitchRollDegrees()

# 配列からYaw,Pitch,Rollを取得
Yaw := Degrees[0]
Pitch := Degrees[1]
Roll := Degrees[2]
```
#### データの使い方
```
# rotation構造体を作る
Rotation := MakeRotationFromYawPitchRollDegrees(Yaw, Pitch, Roll)

# RotationのYawに90度を加える
NewRotation := Rotation.ApplyYaw(90.0)
```
### ⅲ)Translation
XとYは水平方向、Zは高さになります。

#### 取得方法

```
# 位置（vector3）を取得　※FortCharはfort_characterクラスのインスタンスとします
Translation := FortChar.GetTransform().Translation
```

#### データの使い方

```
# vector3の作り方
# Xが1.0、Yが2.0、Zが3.0の位置を表すvector3の作成
Translation := vector3{X:=1.0, Y:=2.0, Z:=3.0}

# vector3のオフセット（vector3同士の計算ができます）
# プレイヤーの位置より、Xを1.0、Yを2.0、Zを3.0マイナスした位置を表すvector3の作成
Translation := FortChar.GetTransform().Translation
OffsetTranslation := Translation - vector3{X:=1.0, Y:=2.0, Z:=3.0}
```

# 3.さいごに
ここまで読んでくださりありがとうございます。
もし参考になったらいいねなど押してくださると嬉しいです。

この記事は、特にRotationの扱い方で「リンゴのゲーム開発」というサイトを参考にさせていただきました。
この方の記事は参考になるものばかりでいつも参考にさせていただいています。ありがとうございます。
https://ringogames.hatenablog.com/entry/2023/04/02/073146
初心者から見たVue3コンポーネントの実装のしやすさについて Vision.6

# Vue3コンポーネントの実装のしやすさについて Vision.6

Vue3のコンポーネントの実装について、前回はVue3コンポーネントの詳細から、
グローバル登録について、まとめました。

前回：グローバル登録

https://qiita.com/babel_0101/items/a643cc19a13cede09ee2

今回は、ローカル登録を以下にまとめます。
## Vue3のコンポーネントの詳細2

公式ページ：[ローカル登録](https://ja.vuejs.org/guide/components/registration#local-registration)を読み進めながら、以下のように解釈。

**ローカル登録(Local Registration):** 単一ファイルコンポーネントのローカル登録は<br>既に[Vue3のコンポーネントの基礎1](https://qiita.com/babel_0101/items/deaf4d50c25a33bcec85)の段階で記述した通り、`<script setup>`と共に使用する例が以下の通りとなります。
```vuejs:anyComponent.vue
<script setup>
import ComponentA from './ComponentA.vue'
</script>

<template>
  <ComponentA />
</template>
```
上記の場合、インポートしたコンポーネントは登録なしで使用可能になります。

`<script setup>`を用いない場合は、以下のように`components`オプションを<br>使用する必要があります。
```typescript:anyComponent.vue
import ComponentA from './ComponentA.js'

export default {
  components: {
    ComponentA
  },
  setup() {
    // ...
  }
}
```
`components`オブジェクトのプロパティそれぞれについて、キーがコンポーネントの<br>登録名になります。そして、値にコンポーネントの実装が保持されます。<br>上の例では ES2015 のプロパティの省略記法を使っていて、これは次の表記と等価です。
```typescript:anyComponent.vue
export default {
  components: {
    ComponentA: ComponentA
  }
  // ...
}
```

このプロパティの省略記法は良く使いますが、よくよく考えてみると<br>[ECMAScript言語仕様](https://262.ecma-international.org/6.0/)に記載されている、どの部分なのか根拠付けが難しいですね。<br>12.2.6 Object Initializer以降のオブジェクトの初期化、名称決定に関する一連の記述かなと<br>ふわっと思うレベルです。

次回：propsの宣言について

https://qiita.com/babel_0101/items/8cf494b6e283fd4aafc4
意外と忘れてしまいがちなshutdownコマンド

linuxの操作の多くはコマンドで実行されている方が多いのではないでしょうか？

ですが、使用回数の少ないコマンドはいざという時に思い出せないなんて事があるかと思います。

今回は意外と忘れてしまいがちなshutdownコマンドについて解説致します。

## 即時シャットダウン

即時シャットダウンは「now」を指定し実行します。

下記コマンドとなります。

```
shutdown now
```

## 指定した時間後にシャットダウン

続いては指定した時間後にシャットダウンする方法です。

下記は例として15分後にシャットダウンするコマンドとなります。

```
shutdown +15
```

## 指定の時刻にシャットダウン

続いては指定した時刻にシャットダウンする方法です。

下記は例として16:00時にシャットダウンするコマンドとなります。

```
shutdown 16:00
```

## 再起動コマンド

続いては指定した再起動する方法となります。

下記コマンドとなります。

```
reboot
```

## キャンセルコマンド

「-c」オプションを指定する事既にスケジュールされているシャットダウンまたは再起動をキャンセルする事ができます。

下記コマンドとなります。

```
shutdown -c
```
AWS Batch

# はじめに

この記事はAWS SAA試験勉強のための、AWS Batchに関する知識のまとめです。

# AWS Batchとは

AWS Batchは、バッチ処理を実行するために必要な機能を含むAWSのフルマネージドサービスです。バッチ処理に必要なジョブ管理や、リソースの動的なプロビジョニングおよびスケーリングをAWSが提供します。

Lambdaと比べると設定と管理が複雑になります。

# 実行環境

実行環境としてEC2やFargate、スポットインスタンス等を選べます。
markdown AI を使ってみた！

Quitaの投稿キャンペーンでmarkdown AI についてがあったので使ってみました！

# markdown AIとは？
Googleアカウントのみで無料使うことができるWebサイト作成支援のwebアプリです。
詳細はこちら

https://mdown.ai/content?id=335b81b2-bcb0-4dbb-83d0-531aa132181f

Markdown記法に慣れている方ならだれでも簡単に使えるものです！

## 使い方
あまり説明することもないのですが、中央のエリアにMarkdown形式で文章を書きます。
Imageを押すと画像を入れることもできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273072/1ffddfe8-13cd-5552-ea1c-7bcf4eb6a9a8.png)

上部にあるViewボタンを押すと今どんな感じで文章が見えるのかの確認ができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273072/3ab6a2e1-652b-e205-4f14-190ca190589e.png)

View画面にあるURLはSaveボタン押下後に活性化され、押下することができます。
押下するとリンクを作成してもいいか確認画面が出ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273072/215d6d06-1bd8-89ab-663c-5b763ecdd80a.png)

ここでPublishを押下すると作成した画面のHTMLのコードを見ることができたり、URLが生成されるのでどのように見えてるのか確認ができます。

# 感想
個人的に良かったことと改善希望点挙げます✨
個人的にはMarkdownはそれなり程度には扱えるので自動でHTMLのコード生成してくれるのはいいなぁと感じました！
- 良かった点
Markdownに慣れている人なら簡単に使うことができること。
MarkdownからHTMLのコードが簡単に生成できるのでデザイン→コード化の際に役立ちそう！
URLが生成されるので簡易的な共有メモ帳として使えそう
- 改善点
Saveボタン押さなければURL生成できないのがわかりにくかった。URLボタン押下時にSaveもできるようにしてほしい。
Quitaの記事を書く感覚で書いたところリンクカード等は使えなかった...あくまでHTMLのコーディングサポート
【UE5】ゼロから極めるゲーム開発　その5(インポート)

# インポート

### テクスチャのインポート

インポートボタンからテクスチャを選択するだけ！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3779049/10e9671d-ebea-edf1-30fe-9b196b71e617.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3779049/62fdac98-2c04-e17c-39e3-f48ab3581c15.png)

### FBXのインポート

そもそもFBXとは...スタティックメッシュのファイル形式のこと。

テクスチャと同じようにインポートボタンから開くと、オプションが表示される
参考書通りにデフォルトの設定からいくつか変更する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3779049/014b55c7-9cc5-671c-bba1-a9760a08dd08.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3779049/8eae6aa6-70a3-bb90-1f36-a636c7f6f65c.png)

### マテリアル作成

テクスチャを右クリックして[マテリアル作成]を選択するだけ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3779049/7f7bb217-9a41-c2ea-d51e-d29575c1c0df.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3779049/fde530a2-eacc-9743-f583-915995617e22.png)

# 突然ですが終わり

インポート系はつまらん。飽きたのでここで終わり！
気が向いたら続きを書きます。早くブループリントいじりたい
【備忘録】fly.ioでLaravelデプロイメント：シンボリックリンクが機能しない問題の解決&マウント方法

# fly.ioでLaravelデプロイメント：シンボリックリンクが機能しない問題の解決

laravelのWEBアプリケーションで画像のアップロード機能などを搭載している場合、一般的にはstorageフォルダ下に保存すると思います。
ローカル環境であれば、アップロードされた画像などを参照する際には以下のようなシンボリックを設定を行うことが多いですが、fly.ioだと結構詰まるポイントがたくさんあったので共有したいと思います。

```
php artisan storage:link
```


# fly.ioとは
一部無料でアプリケーションをデプロイできる。
すげー

# シンボリックを設定する

`fly launch`を行うとルートディレクトリ下にDockerfileが生成されると思います。
そこに`RUN php artisan storage:link`を追加して記述してください。
これで、シンボリックが設定されます。
`fly ssh console`でssh接続をしコマンドを打つ方法もありますが、VMがアイドル状態になると自動的に停止され、何か新しいリクエストが送られるとVMが自動的に再起動されるためシンボリック情報を逐一設定するはめになるので、コンテナが作られるのと同時にシンボリックを設定してもらうよう記述しています。

```dockerfile:
# なんか色々書いてある

RUN php artisan storage:link

EXPOSE 8080
```
# マウントする
シンボリックを設定したからといって、一喜一憂してはいけません。
先ほどの理由で、VMが再起動の行われるとアップロードされた画像が消されてしまいます。
そのため、時間が経った後に自分の作ったwebサイトを閲覧すると画像が正しく読み込まれません。
(404エラーが返ります。）

## 手順１：regionの確認
以下のコマンドを入力して、machine processの数とregionを確認してください。
日本であればregionはnrtで設定されてることが多いと思います、また、machine processの数も２個がデフォルトっぽいです。

コマンド
```
fly status
```
出力例：下の例だとregionはams
```

Machines
PROCESS ID              VERSION REGION  STATE   ROLE    CHECKS  LAST UPDATED         
app     5683945bd46448  1       ams     started                 2023-10-03T09:54:04Z
app     e82d922f010908  1       ams     started                 2023-10-03T09:54:25Z

```

## 手順２:volumeの追加
先ほど確認したregionとマシンプロセスの数を元に以下のコマンドを入力してください。
```
fly volumes create storage_vol --region region名 --count マシンプロセスの数
```

## 手順３:fly.tomlの編集
下の文を追加してください。
```:fly.toml
[mounts]
  source="storage_vol"
  destination="/var/www/html/storage"

```

## 手順４：設定ファイルの追加
シェルスクリプトを作成します。
ファイルを作成した後、以下の記述を書き込んでください。
先頭の1をファイル名に追加しないと、cache.shが先に実行されてしまってうまくいかないっぽいので気をつけてください。
```
touch .fly/scripts/1_storage_init.sh
```
```bash:.fly/config/1_storage_init.sh
FOLDER=/var/www/html/storage/app
if [ ! -d "$FOLDER" ]; then
    echo "$FOLDER is not a directory, copying storage_ content to storage"
    cp -r /var/www/html/storage_/. /var/www/html/storage
    echo "deleting storage_..."
    rm -rf /var/www/html/storage_
fi

```

## 手順５：デプロイ
ここまできたらデプロイしてください。うまくいけばちゃんと機能するはずです。
```
fly deploy
```

# よくあるエラー
手順２にてregionなどの設定を適切に行わないと、`watch your deployment at アプリケーションのURL`の画面でデプロイが終わりません。作成したボリュームはダッシュボード上でも参照できるのできちんと確認しましょう。


# おわりに
参考にした記事を置いておきます。
まだ記事を書くことに慣れていませんので、誤字やまちがった情報などがあれば教えていただければ幸いです。


マウント方法【公式ドキュメント】：https://fly.io/docs/laravel/the-basics/laravel-volume-storage/
JSX(React)のreturn文でifをそのまま使えないのはなぜか？


## 結論から
返り値として1つの**式**を返す必要があるためです。
`if`文は式ではなく文ですので、そのままJSXのreturn 内で使うことはできません。

## JSXと条件分岐
JSX とはReactでも採用されているJavaScriptの拡張構文であり、JavaScriptにHTMLのタグのようなマークアップを記述することができます。
JSXでは、return内の条件分岐は主に論理積演算子`&&`や三項演算子`? :`によって表されることが多いですが、これはどちらも条件分岐を式で表現できる点で`if`とは異なります。

論理積演算子`&&`による条件分岐
```jsx:App.jsx
function App() {
  const random = Math.random();
  return (
    <div>
      {random >= 0.5 && (<div>{random} is greater than or equal to 1/2</div>)}
    </div>
  );
}

export default App;
```
:::note warn
`&&`や`?:`による条件分岐で条件部分が表示されていないのは、JSX がboolean や`undefined`、`null`を表示しないように無視するためです。
`{0 && (<div>No Display</div>)}`のように書くと`0`が表示されてしまいますので`!!`をつけてbooleanに変換するなど対応が必要です。
:::

https://ja.react.dev/learn/writing-markup-with-jsx

### if をreturn 内で使うには
どうしても`if`文を使用したいという場合には、`(()=>{if文})`というような関数を`return`内で実行することで**式**を返すようにすることで、`if`の使用が可能になります（即時関数）。
```jsx:App.jsx
function App() {
  const random = Math.random();
  return (
    <div>
      {(() => {
        if (random >= 0.5) {
          return <div> {random} is greater than or equal to 1/2</div>;
        } else {
          return <div> {random} is less than 1/2 </div>;
        }
      })()}
    </div>
  );
}

export default App;
```
`if`を使用することはできていますが上の例では三項演算子を利用する方が可読性は上がりますね。
```jsx
{random >= 0.5 ? (
        <div> {random} is greater than or equal to 1/2</div>
      ) : (
        <div> {random} is less than 1/2 </div>
      )}
```

分岐が多い場合には`switch`文なども使用することができます。
文であっても、式を返すようにすれば使用可能になります。
```jsx:App.jsx
function App() {
  const random = Math.random();
  return (
    <div>
      {(() => {
        const value = Math.floor(random * 4)
        switch (value) {
          case 0:
            return <div>{`0 <= ${random} < 0.25`}</div>;
          case  1:
            return <div>{`0.25 <= ${random} < 0.5`}</div>;
          case 2:
            return <div>{`0.5 <= ${random} < 0.75`}</div>;
          case 3:
            return <div>{`0.75 <= ${random} < 1`}</div>;
          default:
            return null;
        }
      })()}
    </div>
  );
}

export default App;
```


:::note warn
`if`や`switch`を使用しなければ分岐が煩雑になってしまうような場合には、`return`の外側にロジックを移すことをおすすめします。
:::

## JSX では式を１つしか返せない
```jsx
function App() {
  return(
    <div>a</div>
    <div>b</div>
  )
}
```
上のように２つの要素を返そうとするとエラーが出てしまいます。
これも返り値は1つの式しか認められていないために起きるエラーです。
返り値を1つの式とするために、`<Fragment>`(`<></>`)で要素を囲って返す必要が出てくるわけです。
JavaScriptでの返り値が1つでなくてはならないことと同じ制約ですね。

## JSXに関する余談: サニタイズ
JSX の`{}`構文には、式が自動でエスケープ処理される機能がついています。
XSS脆弱性などを含まないように、`React`が自動で文字列をサニタイズ（消毒）してくれます。
`dangerouslySetInnerHTML`属性によってエスケープ処理をせずに文字列をセットすることも可能ですが、XSS脆弱性を含まないように注意する必要があります。

https://ja.react.dev/reference/react-dom/components/common#dangerously-setting-the-inner-html
httpdでSSL/TLSプロトコルバージョンを指定する方法

今回はhttpdでSSL/TLSプロトコルバージョンを指定する方法について解説致します。

前提条件は以下となります。

* Apacheがインストールされている
* mod_sslが有効になっている
* SSL証明書が用意されている

## 設定ファイルに記述する

SSLに関する記述は通常「ssl.conf」やバーチャルホスト設定内に記述します。

```
vi /etc/httpd/conf.d/ssl.conf
```

※構成に合わせてパスを修正し記述してください。

## TLSバージョンを指定する

今回は例としてTLS 1.2とTLS 1.3のみを有効その他のTLS 1.0やTLS 1.1等を無効化します。

下記設定内容です。

```
SSLProtocol -all +TLSv1.2 +TLSv1.3
```
※ご利用用途に合わせて設定値を変更してください。

## 暗号スイートを指定する


SSLCipherSuiteディレクティブを使用する事で許可する暗号スイートを指定する事が出来ます。

下記設定例となります。

```
SSLCipherSuite HIGH:!aNULL:!MD5:!3DES:!CAMELLIA
```

※ご利用用途に合わせて設定値を変更してください。

## 暗号スイートの優先順位を設定する

SSLHonorCipherOrderディレクティブを設定することで、サーバー側の暗号スイートの優先順位を設定する事ができます。

```
SSLHonorCipherOrder on
```


## 再起動する

最後に設定を読み込む為、Apacheの再起動を行う

再起動前に下記シンタックスチェックを実施し設定値に問題ないか確認してください。

```
httpd -t
```

上記チェックで問題なければ再起動を実施します。

```
systemctl restart httpd
```

以上で設定完了となります!
【マラソン04】メタクエ2が当選してからやったこと

# これはなに？
今回は、4月に我が家に来てからというもの、生活をガラッと変えてしまったMeta quest2について、ざっくり書いていきます。

# 誰向け？
- quest2でどんなことができるのか興味がある方
- quest2を入手するに至った経緯や方法が気になる方
- ゲーミングpcがなくてもquest2単体でできるVRに興味がある方

# あらすじ
2024/3/25、clusterにて、quest2が当たるキャンペーンがあり、
そこで見事当選したため、メタバースやVRにぐいっとハマりました。

## clusterとは
メタバースコミュニティの一つで、VRゴーグルがなくてもPCやスマホ、タブレットから楽しめるメタバースです。
空間内ではボイスチャットの他、テキストチャットやエモートといったリアクションが使えるため、色々な環境でログインして楽しむことができます。
また、イベント風景などをYouTubeにも同時放映できるため、Vライバーさん達も使っている印象です。

## quest2とは
正式名称は Meta quest2。ゲーミングPCがなくてもゴーグル単機でVRを楽しめるのが特徴です。

## 当選キャンペーンについて
イベント自体はcluster公式が毎月行なっているものです。
抽選で1名にquest2が、数名にTシャツが当たる!……というシンプルなイベントでした。

**……まさか、抽選1名様に当たるとは思わないじゃん……?**

## 当選連絡から実際に届くまで
実際に届くまで、どこか信じることができませんでした(笑)
普通に、キャンペーンを利用した詐欺連絡でも来たかな?……と思った程。
当選連絡が来たのも、運悪くエイプリルフールだったので(笑)

……この辺の話も話せば長くなるので1つの記事になりそうですね。

# quest2でやってみたこと
### cluster
上述のメタバースコミュニティにて、早速使いました。
スマホやPCでも入れますし、VRゴーグルをつけなくても1人称視点は選べるのですが、やはり**VRとなると没入感が全然違いました。**
椅子に座りながらも体を動かせる、身振り手振りを加えられる、表情も動かせる……！
**本当にその世界に入って生きている……！**と実感する程。
特に、接客イベントでのキャストさんとの距離がとても近くなりました。視線が合う感覚やちょっとしたふれあいなど。
VRでログインしないと見えない情報がたくさんあると思いました。

このあたりは別記事で詳しく書ければと思います。

### TDPT
iPhone1台でフルトラッキング(=全身の動きをアバターに反映)できるアプリです。
VRでclusterに入れたので、フルトラしてダンスしたりもできる……？と調べていたところ、cluster内のコミュニティでトラッキング機材がなくてもスマホでトラッキングできることを教えてもらいました。じ、時代……！
実際に使ってみると、普段のヘッドセットと両手の3点では、表現できなかった腰の動きが入ります。それだけでとてもアバターの動きがリアルに近づくなと感じました。

もちろん、フルトラッキングの中では、トラッキング機材を使うよりも精度が落ち、カクつきなどは少し出ている気がします。
ただ、高値のトラッキング機材を購入する前に、フルトラッキングはどういうものなんだろう？……というのを体験するのにはちょうどいいと思いました。
なお、フルトラッキングを導入する場合には、買い切りで600円の課金をする必要があります。
ただ、月額課金等はなく、買い切りで一度払ってしまえば終わりなので、そこまで高い買い物には感じませんでした。

### ビートセイバー
VRで音ゲーといえばこれということで、ご存じの方も多いのではないでしょうか。
コントローラ2台から出ているライトセーバーで、前方から飛んでくる物体を切る！
とても分かりやすく、シンプルで爽快なゲームです。
modを導入することで、Youtubeで見るような自作アバターでのプレイ動画を作ることもできます。
実際に飛んでくる物体を切ったときに、コントローラーにバイブレーションのフィードバックがあるので、とても没入感があって楽しいです。
また、軽い有酸素運動としてもできるので、継続することでダイエットなどの効果も期待できそうです。

このあたりもまた、別記事で詳しく書ければと思います。

### immersed
VRデスクトップ環境の構築ができるソフトです。
questで映し出されたVRカフェ空間などに、PCのデスクトップ画面を映し出して作業することができます。
iPhoneやiPadもアプリを入れることで同じVR上に映し出せるのが地味に便利。
無料でここまでできていいの？……というレベルで重宝するアプリです。
PC画面は最大で5画面まで出すことができます。プログラミング中など複数の窓を開き、比較をした作業の時にとても便利です。
使い始めた使い始めは3画面までしか出すことができませんが、10日間の期間のうち三日間利用することで、プロと同じ制限なしのモードが使えるため、特に課金をせず使うことが可能となっています。

これも詳しくは別記事で書きます。

# ざっくり、どんなことができるのか
**なんかもう、なんでもできます（笑）**
immersedでPC画面を見ながら仕事や作業もできますし、ゲームも交流もできる。
私はパソコンのスペックが低いので、基本的にクエスト単騎で行う作業しかしませんが、ゲーミングPCを持っている人であれば、PCのスペックを軸に高画質や高品質なVRを楽しむことができるそうです。

苦手があるとすれば、紙にペンで書くようなアナログな作業。
ただ、苦手なだけで、VR空間でもペンで描画する方法はできているので、
今後書きやすくなっていくかもしれません。

また、quest2は充電が切れるのが早いため、長時間の利用の際はバッテリーをつなぐか、パソコンなどに有線でつないで使うといいです。
JavaScriptにおけるイベント

# JavaScriptにおけるイベント
 ユーザーの操作やブラウザの動作によって発生するアクションを指します。イベントは、ユーザーとウェブページとのインタラクションを処理するために使用されます。以下に、いくつかの主要なイベントとその説明を示します。

# マウスイベント
click : ユーザーが要素をクリックしたときに発生します。
dblclick: ユーザーが要素をダブルクリックしたときに発生します。
mousedown: ユーザーがマウスボタンを押下したときに発生します。
mouseup: ユーザーがマウスボタンを放したときに発生します。
mousemove: ユーザーがマウスを動かしたときに発生します。
mouseover: マウスポインターが要素の上に乗ったときに発生します。
mouseout: マウスポインターが要素から離れたときに発生します。
mouseenter: マウスポインターが要素に入ったときに発生します。バブリングしません。
mouseleave: マウスポインターが要素から出たときに発生します。バブリングしません。

# キーボードイベント
keydown: ユーザーがキーを押下したときに発生します。
keyup: ユーザーがキーを放したときに発生します。
keypress: ユーザーがキーを押下したときに発生します。keydown と keyup の間に発生しますが、現在は非推奨です。

# フォームイベント
submit: フォームが送信されたときに発生します。
reset: フォームがリセットされたときに発生します。
focus: 要素がフォーカスされたときに発生します。
blur: 要素からフォーカスが外れたときに発生します。
change: フォーム要素の値が変更されたときに発生します。

# ウィンドウイベント
load: ページが完全に読み込まれたときに発生します。
resize: ウィンドウのサイズが変更されたときに発生します。
scroll: ページがスクロールされたときに発生します。
unload: ページがアンロードされるときに発生します。

# タッチイベント（モバイル向け）
touchstart: ユーザーがタッチデバイスで画面に触れたときに発生します。
touchmove: ユーザーがタッチしたまま指を動かしたときに発生します。
touchend: ユーザーがタッチした指を画面から離したときに発生します。

# その他のイベント
input: 入力要素の値が変更されたときに発生します。change イベントと異なり、リアルタイムで発生します。
contextmenu: コンテキストメニュー（右クリックメニュー）が表示されたときに発生します。






 ※この記事はChatGPTの検索結果をもとに作成しています。
自分のためのDockerあれこれ

# はじめに

Dockerのコマンドを使っていて、引数なんだっけ？オプションなんだっけ？この出力結果はどういう意味なんだっけ？となることが多いです。
ここに記載しているのは、基本的なコマンドです。
あくまで自分のためなので、あしからず。
徐々に追加予定です。
**※docker-composeについては別記事で記載しようと思っているため、あえて載せていません。**

# 表示系
## docker images

docker imageの一覧を表示するコマンド。

### オプション

|コマンド|説明|
|:---|:---|
|--all, -a|全てのイメージを表示|
|--quiet, -q|イメージIDのみを表示|
|--no-trunc|省略せず出力|


## docker ps

コンテナの一覧を表示するコマンド。

### オプション

|コマンド|説明|
|:---|:---|
|--all, -a|全てのコンテナを表示|
|--quiet, -q|コンテナIDのみを表示|
|--no-trunc|省略せず出力|
|--size, -s|合計の容量を表示|


# 操作系

## docker build

Dockerfileからイメージを作る。

### オプション

|コマンド|説明|
|:---|:---|
|--file, -f|Dockerfileを指定|
|--no-cache|キャッシュを使用しない|
|--rm|中間コンテナを削除|
|--tag, -t|名前:タグの形式でタグを指定|

## docker run

コンテナを立て、コマンドを実行する。

### オプション

|コマンド|説明|
|:---|:---|
|-i|対話型で標準入力を開き続ける|
|-d|バックグラウンドで実行|
|-e|環境変数を設定|
|-t|擬似ターミナルを作る|
|-v|ボリュームをマウントする|
|-p|ポート番号のマッピングを指定|
|--name|コンテナの名前を指定する|
|--network|コンテナをネットワークに接続|

## docker exec

実行中のコンテナ内でコマンドを実行する。

### オプション

|コマンド|説明|
|:---|:---|
|-i|対話型で標準入力を開き続ける|
|-d|バックグラウンドでコマンドを実行|
|-e|環境変数を設定|
|-t|擬似ターミナルを作る|
Power Appsのフォームのコントロールを変更する方法

# やりたいこと
フォームのデータソースに下図のようなSharepointリストを指定すると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670355/2ad52468-0e13-edc9-d328-ef5941b051d2.png)
↓のようなフォームが生成されますが、、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670355/3abfc45d-5f0d-77b0-8cd1-6143334a6186.png)
元のリストは一行テキストなんだけど、アプリ側で選択肢にしたいから<strong>コンボボックス</strong>にしたい！というような時の方法。
コンボボックス以外でも同様。

# 方法
### Step1 変更したいコントロールを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670355/092d22a8-1f2e-64a1-e847-9a85e67eb734.png)

### Step2 目的のコントロールを挿入（同時にロック解除）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670355/2539f57f-a701-f0f5-4ce8-ebb474a6b7eb.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670355/b8ec5214-0e8c-2996-5746-6b79270cdf5d.png)

### Step3 新コントロールのプロパティを整える
元のコントロールとレイアウト揃えてみたり、items等々。

### Step4 元のコントロール名を置換
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670355/e111528a-0eb1-b2e2-8715-ed514045891c.png)
元のコントロール名を新コントロール名に置換しようとするとエラーが出るのでチェック外しておく。

DataCardのUpdateプロパティを新コントロール名で置換しておくのがポイント。

### Step5 発生したエラーを修正
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670355/fba507e8-aa90-6ccd-1a5f-4135d8f49e07.png)

### Step6 元のコントロールを削除
以上！
VPCのクライアントVPN エンドポイントは注意すべし（費用面で）

## 経緯
社内ネットワークを模倣したVPCを作成したため、クライアント(自分のPC)とVPCのクライアントVPN エンドポイントというものを使用して、VPN接続を行った。

↓のVPCの仮想プライベートネットワーク(VPN)で設定できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/75a7f45f-b87b-7ace-1a60-0994513d5ccf.png)

OpenVPN GUIで接続できたのを確認し、不要リソースを削除していった。(ここまでで、意外と時間がかかった。)

次の日、Budgetsを確認してみると、
```
Amazon Virtual Private Cloud ClientVPNEndpoints                 USD 0.88
 $0.15 per Client VPN Endpoint Association Hour  5.853 Hourly	USD 0.88
```
`$0.15 per Client VPN Endpoint Association Hour`
Client VPNエンドポイントの関連付けが1時間続くごとに、0.15ドルが課金されていた。
使用した時間が5.853時間のため合計で0.88ドルの料金が発生していた。

あまりないとは思うが、VPN接続しっぱなしだと意外とほかのサービスに比べお金がかかる、、(0.005ドルのような小数点第3位の金額のサービスを見慣れているからでしょうか？)

## クライアント VPN エンドポイントとは？
そもそも、クライアント VPN エンドポイントとは何かというと
リモートユーザーやリモートオフィスがAWSの仮想プライベートクラウド（VPC）内のリソースに安全にアクセスするために、作成できるエンドポイントです。
エンドポイントを作成し、クライアント設定をダウンロードします。
その後、OpenVPN GUI等でVPCにVPN接続することができます。
[クライアント VPN エンドポイント](https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/cvpn-working-endpoints.html)

## 終わりに
今回は、そこまで長い時間VPN接続を行わなかったため、大きな額とはならなかったが、仮にVPN接続しっぱなしにしていたとしたら円安もあり恐ろしい。
皆さんもクライアントVPNエンドポイントを使う際はお気を付けください。
さくらVPSのUbuntu環境でGoogleDriveの共有ドライブをマウントする

# 背景
VPSサーバで何かしらのデータのバックアップを取っておきたいときに、バックアップを同一サーバ内に保存しておくでも良いが、手違いやアクシデントなどでサーバ自体のデータが消失したときのために、Ubuntu上からGoogle Driveにアクセスして保存しておけたら便利かと思ったため。また、サーバ上だとバックアップデータの取得のためにSFTP接続などが必要になるが、Google Driveだとアクセスも容易なため。

# 環境
OS: Ubuntu 22.04 LTS

# 設定手順

## Google CloudでOAuthクライアントIDを作成する
OAuthの認証情報が必要になりますのでGoogle Cloudにアクセスして作成します
https://console.cloud.google.com/

手順は下記の通りです

### プロジェクトがない場合はまず最初にプロジェクトを作成

### Google Drive APIで検索して有効化
![ss1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245797/6e3f1efd-39dd-0213-9bdd-bb1b85b9cd40.png)

### APIとサービス → OAuth同意画面の作成
![ss2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245797/25285d30-5345-503b-ae38-fa811441cf70.png)

Internalを選ぶと組織内部のみの認証ができます

### APIとサービス → 認証情報の作成
![ss3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245797/1ceeaab6-fb32-1977-2b10-5e85ffb9d464.png)
種類はデスクトップアプリを選択

上記でできあがったクライアントIDとクライアントシークレットを使用します。

## Ubuntuでの設定

### google-drive-ocamlfuseをUbuntuにインストール
```
sudo add-apt-repository ppa:alessandro-strada/ppa
sudo apt-get update
sudo apt-get install google-drive-ocamlfuse
```

### 認証を行う

この状態で
```
google-drive-ocamlfuse
```
とコマンドを打つと以下のエラーが出ます

```
/bin/sh: 1: xdg-open: not found
/bin/sh: 1: firefox: not found
/bin/sh: 1: google-chrome: not found
/bin/sh: 1: chromium-browser: not found
```

google-drive-ocamlfuseはGUIのブラウザで認証を求めるものであるため、GUI環境のない場合には上記のようなエラーが出ます。

そこでCUI環境のみの場合にはheadlessで認証を行います。
```
google-drive-ocamlfuse -headless -id クライアントID -secret クライアントシークレット
```
クライアントIDとクライアントシークレットには最初の手順で作成したものを入れてください。コマンドを打つと以下が表示されます
```
Please, open the following URL in a web browser: https://accounts.google.com/o/oauth2/auth?client_id=hogehoge&redirect_uri=http%3A%2F%2F127.0.0.1%3A8080%2Foauth2callback&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive&response_type=code&access_type=offline&approval_prompt=force
Please enter the verification code:
```
`Please, open the following URL in a web browser:`
で示されたURLをブラウザで開きます。そしてを認証で許可を行うと以下のようなページにリダイレクトされます
```
http://127.0.0.1:8080/oauth2callback?code=hogehoge&scope=https://www.googleapis.com/auth/drive
```
上記のcodeのパラメータhogehogeをコピーしてverification codeに入力すると認証完了です

## Google Driveのマウント
マイドライブをマウントしたい場合には特に何も設定せず以下のようにコマンドを実行
```
mkdir GoogleDrive
google-drive-ocamlfuse ./GoogleDrive
```

今回は共有ドライブをマウントしたいので`~/.gdfuse/default/config`を編集する必要があります。
ファイル内のteam_drive_idにIDを設定、IDの調べ方はドライブのルートURLのhogehoge部分です
```
https://drive.google.com/drive/folders/hogehoge
```

```~/.gdfuse/default/config
team_drive_id=hogehoge
```

上記を変更した後にドライブをマウントすると共有ドライブをマウントすることができます。（設定が反映されなかった場合には設定後に再度認証を行うと反映されたりしました。）


ドライブをアンマウントしたいときは
```
fusermount -u ~/GoogleDrive
```

うまくマウントできない場合などのキャッシュクリア
```
google-drive-ocamlfuse -cc
```
## 最後に
サービスとして自動でバックアップを取ってくれるもの以外では適切なバックアップ方法を模索する必要があると感じました。他にも良い方法がないかを検討していけたらと思っています。

以上です。


# 参考
https://github.com/astrada/google-drive-ocamlfuse

https://qiita.com/kahibella/items/9cb729f1ce46c9dc0f63

https://qiita.com/cabbage_lettuce/items/c4544b3e5cd28caf04bc
[備忘録] ネットのテック記事  (ロボット・物流編)

# 備忘録

複数の物流事業者の荷物配送状況を一括管理する「共同配送システム」を構築
https://monoist.itmedia.co.jp/mn/articles/2406/17/news082.html

[備忘録]
- 荷物の配送状況を一括で管理する「共同配送システム」を構築
- 配送を担う業者が複数の物流事業者の荷物をまとめて配送する「共同配送」を対象
- 荷物に貼り付けられた伝票のバーコードを専用端末でスキャンする

ネコ型配膳ロボで実績、産業用途向け搬送ロボットを日本市場へ投入へ
https://monoist.itmedia.co.jp/mn/articles/2406/18/news044.html

[備忘録]
- 産業用途向けの搬送ロボットを開発
    - 物流現場の省人化を目指す

- ロボットはマーカーなしでナビゲーションを行う
    - 設備の再構築は不要
    - Iotも導入してアプリケ経由での電話操作や生産ラインからの資材リクエストに対応する
    - システムを容易に統合するソフトウェアAPIインタフェースも提供

- ロボットの位置や走行経路は操作表示灯と交通信号灯が明確に表示する
    - ボタンは作業の意向や設備に合わせてカスタマイズすることが可能
    - アラーム音によるリマインダー機能もあり


高い自律性と安全性を備えた、ドイツの清掃機器専門メーカーの床洗浄ロボット
https://monoist.itmedia.co.jp/mn/articles/2304/27/news086.html

[備忘録]
- 視野型マルチセンサーシステムが瞬時に360度ビューを作成
- ロボットが後退をして自立復帰を行う
- 2種類のマッピング方法で洗浄ルートの設定や編集、ロボット操作が可能
- 最新のリチウムイオンバッテリーにより小型化
Jetson nanoで、Dockerプログラムを自動起動にする

Jetson nano（Ubuntu）で、
組み込み機器ライクに、電源を入れるだけで（マウスやキーボードなしに）プログラムを起動させたい。

でも起動させたいプログラムがDockerベースで動いておりました。

Docker初心者が、いろいろガチャガチャやって、やっと動いたので備忘録として残します

---

# 動かしたいプログラム

https://github.com/dusty-nv/jetson-inference

こちらのJetson-inferenceです。
posenetのプログラムを動かしたいです。

---

# 手動起動で動作確認

https://qiita.com/vfuji/items/3a2535fd402b5cf77506

こちらの記事を参考に動かしました。
    
    git clone --recursive --depth=1 https://github.com/dusty-nv/jetson-inference
    cd jetson-inference
    docker/run.sh

でDockerを起動させたあと、

    posenet.py csi://0

によって、Posenetを起動できました。

---

# 自動化手順

1. Dockerコンテナを起動するシェルスクリプト用意し、name オプション付きでDockerを起動するように設定します
2. Jetsonにある「Startup Applications Preference」で、Docker起動スクリプトを自動実行設定します。
3. Jetsonにある「Startup Applications Preference」で、nameオプションでコンテナ指定してDocker実行するようにします。
4. sudoでパスワードを聞かれるので無効化します（！）

おおよそこんなかんじです。

---

# 1. Dockerコンテナを起動するシェルスクリプト用意し、name オプション付きでDockerを起動するように設定します

jetson-inference/docker/run.sh のスクリプトで、コンテナネームを指定してください　[container_name]

    (前略)
    # run the container
    if [ $ARCH = "aarch64" ]; then
    
        # /proc or /sys files aren't mountable into docker
        cat /proc/device-tree/model > /tmp/nv_jetson_model
    
        sudo docker run --runtime nvidia -it --rm \
       	 --network host –name [continer_name] \
            ….
    (後略)

# 2. Jetsonにある「Startup Applications Preference」で、Docker起動スクリプトを自動実行設定します。


「Startup Applications Preference」を実行して、下記のcommandを設定します。

（docker起動用）
    
    gnome-terminal -e “bash -c ‘/path/to/jetson-inference/docker/run.sh;$SHELL’”


# 3. Jetsonにある「Startup Applications Preference」で、nameオプションでコンテナ指定してDocker実行するようにします。

同じく「Startup Applications Preference」を実行して、下記のcommandを設定します。
[container_name] には先程指定した名前を設定します。

    gnome-terminal -e “bash -c ‘/usr/bin/docker exec [my_container] posenet.py csi://0;$SHELL’”


# 4. sudoでパスワードを聞かれるので無効化します（！）

docker起動時にsudoでパスワードを聞かれて自動実行がうまく行きませんでした。
（途中で止まってしまう）

セキュリティ要件とご相談ですが、今回はパスワードを無効化して対応しました。

    sudo visudo

[username]のところに、jetsonのユーザー名を入れて、NO PASSWORD設定を行いました。

    # Allow members of group sudo to execute any command
    %sudo  ALL=(ALL:ALL) ALL
    [username] ALL=NOPASSWD: ALL


---

以上で、なんとか自動起動するようになりました。

cronやsystemctlとかで色々試しましたが、いずれもうまくできなく回り道したので、まあ大変でした（ただの苦労話）
どなたかの助けになれば幸いです。
Linuxでグラボを使いたい(備忘録)


# TL;DR

LinuxでNVIDIAのグラフィックボードを利用したいとき，以下のコマンドを実行してドライバをインストールする

```
sudo apt-add-repository contrib non-free
sudo apt install nvidia-driver -y
sudo reboot
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1206897/5a1027f3-fef3-af6b-3618-68a9c39473cb.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1206897/8a54a6d2-c5e3-a216-ec99-4ca3438e4eaf.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1206897/80fa2b6e-579c-8b83-34ff-41a71e1cf8cd.png)
【Unity】UI ToolkitでSerializedReferenceのSerializeFieldをInspectorに表示したい

# 自己紹介
U/DAYに参加できそうで、ニコニコな大学生

# 今回やること
## 前回…

https://qiita.com/AtsuAtsu0120/items/95d31196813f63dfc413

前回、上記の記事で`SubClassSelector`と呼ばれるエディター拡張をUI Toolkitで再現してみるというのをやりました。

## その続き
今回はその続きで、`SerializeReference`に登録したクラスがもつ`SerializeField`をInspectorから触れるようにします。

# ソースコード
```csharp
    // CreatePropertyGUIの中（詳しくは前回の記事で）
    
    foreach (SerializedProperty serializedField in property.Copy())
    {
        var element = new PropertyField(serializedField, serializedField.displayName);
        root.Add(element);
    }
```

## propertyをforeachで回す
`property`を`foreach`で回すと、その子である`SerializedField`がすべて取得できます。
これちょっとわかりにくいですね。

## よく分からないPropertyの仕様
当初以下のコードを書いていました。
```csharp
    foreach (SerializedProperty serializedField in property)
    {
        var element = new PropertyField(serializedField, serializedField.displayName);
        root.Add(element);
    }
```
`Copy`メソッドを使っていないんですね。
これをすると、２回目以降に大きなバグが発生しました。
propertyが参照する値が、別の変数に置きわかっているようです。

詳細を追う時間もなく、技術もなかったので詳しくは不明ですが、for文を直接回すことで内部的に何かが変わるんでしょうね（適当）

もしわかる人がいたら教えてほしいです。

### 回避方法
`Copy`メソッドを使って、回避することができました。
ここで`Copy`しているのにもかかわらず、正しく値が更新されるのも不思議な挙動ですよね。

# まとめ
あとは一段ずらすだけなのですが、まぁUSSの問題ですし本題とはそれるので、この辺で。
SerializePropertyやその周辺知識があればもっと簡単だったのでしょうが、私はまだまだ勉強不足で、まぁまぁ苦戦しました。
ネストしたObjectからキーを全て取得するユーティリティ型

```ts
type Maybe<T> = T | null | undefined;
type NestedKeyOf<T extends Record<string, unknown>> = {
  [K in keyof T & string]: T[K] extends Maybe<Record<string, unknown>>
    ? T[K] extends Maybe<Record<string, unknown>>
      ? `${K}.${NestedKeyOf<NonNullable<T[K]>>}`
      : K
    : K;
}[keyof T & string];
```

以下の `User` 型を与えてみる

```ts
type User = {
  id: string;
  name: string;
  age?: number | null;
  category: string;
  email: string;
  address?: {
    city: string;
    country: string;
  } | null;
};
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18973/ff460e1b-68e4-acf8-3b49-2bd0eed139a6.png)

参考: https://medium.com/xgeeks/typescript-utility-keyof-nested-object-fa3e457ef2b2
【ROS2 パラメータTips】ネスト化されたパラメータの利用方法

# はじめに
* ROS2のパラメータでネスト化された（入れ子構造）パラメータを利用する方法
* カテゴリごとに階層化して、パラメータを見やすくする際に便利

# 動作確認環境
* ROS2 Dashing/Foxy

# 方法

YAMLファイルの記述方法と、ノードパラメータ宣言方法を各々示す。

## YAMLパラメータファイルの記述

```yaml
test_node:
    ros__parameters:
        category:
            int_value: 1
            str_value: "test"
```

## ノードパラメータの宣言

```.```でパラメータをつなぐことでネスト化する。今回の例は2階層なので、```.```は1つだが、3階層以上の場合は、```.```を2つつなげることで可能(詳細は[参考](https://answers.ros.org/question/325939/declare-nested-parameter/
)を参照)。

### C++ (rclcpp)

rclcpp::Node
```cpp
this->declare_parameter<int>("category.int_value", 0)
this->declare_parameter<std::string>("category.str_value", "")
```

### Python (rclpy)

rclpy.Node
```python
declare_parameter('category.int_value', 0).value
declare_parameter('category.str_value', '').value
```

# まとめ
　パラメータをネスト化する方法を紹介した。1つのノード内で、パラメータをカテゴリ分けして視認性をよくするのみ便利。

# 参考

https://answers.ros.org/question/325939/declare-nested-parameter/
【TryHackMe】Welcome：Walkthrough

# 概要

TryHackMe「Welcome」のWalkthroughです。

# Task2

## **Q1**.*What is the flag text shown on website of the machine you deployed on this task?*

ブラウザでアクセスするとフラグが表示されます。

![flag.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/bae58a41-fc70-98ed-c18d-16a1e0a71e39.png)

**A**.**flag{connection_verified}**
UmbrelOSをPCにインストール後、起動できない問題の回避法

# 記事の概要
LightningNetworkのノードを簡単に立ち上げられるOS「UmbrelOS」の正式版が3/21にリリースされたので、古いPCにインストールしようとしたところ、起動できなかったので回避方法を共有します。

https://umbrel.com/umbrelos

# 問題点
[公式のインストールガイド](https://github.com/getumbrel/umbrel/wiki/Install-umbrelOS-on-x86-systems)に沿ってUSBにisoを焼いて、PCの内蔵SSD(SATA)にインストールしたが、ブートデバイスとして認識されない。
![スクリーンショット 2024-06-17 22.21.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677129/0090b805-8488-daf0-3783-7f18ddf935b8.png)

<details><summary>筆者の環境</summary>
ESPRIMO Q556<br>
CPU : pentium G4600<br>
RAM : 8GB<br>
SSD : 内蔵SATA接続1TB<br>
UEFIブート : 有効<br>
レガシーブート : 有効<br>
</details>


# 結論（解決法）
外付けUSBストレージにインストールすると起動できるようになる。

参考にしたサイト

https://community.umbrel.com/t/bootable-device-not-found/16709/4

# 考察
おそらくラズパイでの動作を前提として作られているOSなので、内蔵ストレージ系のドライバが不足しているのではないか。
リリースしてまもないOSなので、今後のアップデートで修正される可能性あり。
無料とはいえお金を扱うシステムで不具合があると少し不安になる不安
wcコマンドで文字数を数える方法

linuxでファイルの文字数を数えたいと思った事はありますか？

今回はlinuxでファイルの文字数を数える方法をご紹介致します!

## wcコマンドを使用する

wcコマンドを使用するとファイル内の行数や単語数、バイト数をカウントする事が出来ます。

今回は例として1行に100文字が合計1000行あるtest.txtファイルを使用します。

## 文字数をカウントする

文字数をカウントするにはwcコマンドの「-m」オプションを使用します。

```bash
#コマンド
wc -m test.txt

#結果
100000
```

## 行数をカウントする

行数をカウントするにはwcコマンドの「-l」オプションを使用します。

```bash
#コマンド
wc -l test.txt

#結果
1000
```

## 標準入力からのカウント

パイプを使用する事で標準入力からのデータをカウントすることもできます!

下記はlsコマンドの標準出力行数をカウントする例となります。
```bash
# コマンド
ls | wc -l

# 結果
12
```