OmniAICreator/Qiita-1.07M huggingface dataset:
scratchのブロックで説明するif文・while文・for文 python入門

## はじめに
私がscratchをやっていた状況からpythonをやろうとしたとき、最初はscratchでいうこのブロックはpythonでいうこれなんだなというような形で学んでいました。その経験から、まずはscratchで例えるとif文・while文・for文など簡単に理解できるのでは(特にfor文)と思いこの記事を書くことにしました。

### 前提知識
「print()」 「変数」　「配列(リスト)」

## if文・while文
書き方や条件式は後程説明します。まずはif文・while文は何なのかのみ抑えてください。
### if文
まず最初にif文とはscratchでいうこちらです。
![スクリーンショット (70).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3975134/18d47bc5-0fb9-c722-09f3-97a64f7a637b.png)

### while文
まず最初にif文とはscratchでいうこちらです。これは見覚えがない方がほとんどだと思います。ターボワープというサイト限定であるブロックです。簡単に言えばscratchにある「~まで繰り返す】」の逆です。そのため、scratchから始める場合最初は慣れない方が多いかもしれません。
![スクリーンショット (69).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3975134/f8a3c25a-bc9b-c55f-f00e-1bf93334c4d5.png)

### pythonでの書き方
両方似ています。
```python
if 条件式:
    動作

while 条件式:
    動作
```
では条件式は何かというと例えばこの2つでやっていることは同じです。
左と右の値が同じならその中の動作をするようにしています。

【等しいなら~・等しい間~】
![スクリーンショット (71).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3975134/9880ce6d-de42-b98a-979c-4081094da7bc.png)
```python
#等しいなら~
if 1 == 1:
    print("yes")

#等しい間~
while 1 == 1:
    print("yes")
```
このような感じでどんどん貼っていきます。
(スクラッチ版で見てほしいのは緑の部分なのでifのみを貼ります)

【等しくないなら~・等しくない間~】
![スクリーンショット (72).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3975134/d6c1175b-4256-5cd3-928d-273d98a3564a.png)
```python
#等しくないなら~
if 1 != 1:
    print("yes")

#等しくない間~
while 1 != 1:
    print("yes")
```

【左より右の方が大きいなら~・左より右の方が大きい間~】
![スクリーンショット (73).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3975134/ed64ef1e-f66d-ca8a-9269-dfc4defd6411.png)
```python
#左より右の方が大きいなら~
if 1 < 2:
    print("yes")

#左より右の方が大きい間~
while 1 < 2:
    print("yes")
```

【右より左の方が大きいなら~・右より左の方が大きい間~】
![スクリーンショット (74).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3975134/9f9829df-c5ce-8778-5ca8-00f4f4ecb994.png)
```python
#右より左の方が大きいなら~
if 2 > 1:
    print("yes")

#右より左の方が大きい間~
while 2 > 1:
    print("yes")
```
このように沢山あります。scratch版だと混乱するかもしれないので一応~以上・~未満はpythonのみで貼ります。
```python
#変数:varは1以上なら
if var >= 1:
    print("yes")

#変数:varは1以下なら
if var <= 1:
    print("yes")
```

## for文
まず例文を貼ります
```python
for i in range(3):
    print(i)
```
実行結果
```
0
1
2
```
初めは難しそうに感じるかもしれませんがscratchに置き換えると簡単です。
![スクリーンショット (76).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3975134/5fccf3af-bef9-0846-cc26-e719e3820386.png)
実はこれだけなんです。range(3)というのは3回繰り返すということで、iという変数を一回の繰り返しごとに1増やすというような感じです。ちなみに知っている方もいるかもしれませんが、多くのプログラミングでは0から始まります。そのため、このfor文でも最初にiにあるのは0,次に1,最後に2となっています。

ちなみにもちろんiは変数なのでiという名前にしなくてもいいのですが、一般的にはiが使用されることが多いです。


## 最後に
for文に関しては
(https://qiita.com/itijuku/items/7e421d2c791f97b9ba9c)
こちらで具体的な内容まで説明しています。scratchのブロックで説明している訳ではありませんが、良ければご参照お願いします。
【AWS SAP】Route 53 Resolver インバウンド/アウトバウンドエンドポイントとは

# 自分の理解
DNSのキャッシュDNS？

## Route 53 Resolver インバウンド/アウトバウンドエンドポイントとは
- **インバウンド**エンドポイントとはAWS内のVPCのDNSクエリを受け付ける機能（DNSでいうところのキャッシュDNSサーバ）
- **アウトバウンド**エンドポイントとはVPCから外部DNSサーバーへクエリを転送する機能（DNSでいうところのフォワーダー機能）

※エンドポイントの実体はENI

## Route 53 Resolver インバウンドエンドポイント
```mermaid
flowchart TD
    A[オンプレミス クライアント] -->|DNSクエリ送信<br>例: db.internal.example.com| B[**インバウンド<br>エンドポイント**]
    B --> C[VPC内 Resolver<br>（.2アドレス）]
    C -->|プライベートホストゾーンを照会| D{レコードが存在するか?}
    D -->|はい| E[解決済みIPアドレスを返す<br>例: 10.0.0.10]
    D -->|いいえ| F[外部DNSサーバーにフォワード]
    F --> G[外部DNSで解決<br>例: 10.0.1.20]
    G --> E
    E --> B
    B -->|解決済みIPアドレスを返送<br>例: 10.0.0.10| A
```

## Route 53 Resolver アウトバウンドエンドポイント

```mermaid
flowchart TD
    A[VPC内 クライアント] -->|DNSクエリ送信<br>例: external.example.com| B[VPC内 Resolver<br>（.2アドレス）]
    B -->|Resolverルールに基づく転送| C[**アウトバウンド<br>エンドポイント**]
    C --> D{転送先DNSサーバーに到達可能か?}
    D -->|はい| E[転送先DNSサーバーへ転送<br>例: 203.0.113.10]
    D -->|いいえ| F[エラーを返す]
    E --> G[転送先DNSで解決<br>例: 192.0.2.10]
    G --> C
    C --> B
    B -->|解決済みIPアドレスを返送<br>例: 192.0.2.10| A

```
最近のMacOSのターミナルでNASに入れない問題

# Operation not permitted

環境：
```
  機種名:	MacBook Pro
  機種ID:	MacBookPro15,4
  プロセッサ名:	クアッドコアIntel Core i5
  プロセッサ速度:	1.4 GHz
  プロセッサの個数:	1
  コアの総数:	4
  二次キャッシュ（コア単位）:	256 KB
  三次キャッシュ:	6 MB
  ハイパースレッディングテクノロジー:	有効
  メモリ:	8 GB

  システムのバージョン:	macOS 14.7.2 (23H311)
  カーネルのバージョン:	Darwin 23.6.0
```

NASにアクセスしようとしてlsコマンドを打ったり、cdでNAS内に入ろうとすると、
```ls: .: Operation not permitted```
などと言われて先に進めない。

これはデフォルトでターミナルに権限が与えられていないからで、

「システム設定」→「プライバシーとセキュリティ」→「ファイルとフォルダ」→「ターミナル」と選んで、「ネットワークドライブ」のスライドスイッチをONに入れる。

または

「システム設定」→「プライバシーとセキュリティ」→「フルディスクアクセス」と選んで、「ターミナル」のスライドスイッチをONに入れる。この設定の方が強い権限なので、ONにすると上の設定は現れなくなる。
AWSインフラ構築時のエラー対処備忘録2

AWSインフラ構築時のエラー対処備忘録

ECSコンテナサービスを作成中に、バックエンドサービスの作成を実行した際、サーキットブレーカーが発動してエラーが発生した事例について記録します。

使用技術

・フロントエンド
　　UIフレームワーク：Nuxt.js(Vue.js), Vuetify
　　HTTP通信：axios
　　コード整形：ESLint/Prettier
・バックエンド
　　言語・フレームワーク：Ruby 3.1.3・Rails 7.0.4
　　コード品質：RuboCop
　　テスト：RSpec
　　サーバー：Nginx, Puma
　　データベース：MySQL 8.0.31
・インフラ/デプロイメント
　　コンテナ：Docker
　　クラウド：AWS (ECR,ECS,Fargate,VPC,S3,Route53,ALB,RDS,ACM,SSM,CloudWatch)
　　IaC(インフラコード化) ：Terraform
　　CI/CD ：GitHub Actions


エラーが発生するまでの手順は以下の通りです。
(1)タスク定義作成
(2)サービス作成
その後、AWS画面上に以下のエラーメッセージが表示されました。

```
Resource handler returned message: "Error occurred during operation 'ECS Deployment Circuit Breaker was triggered'." (RequestToken: cdf432b2-ef09-f7cc-074d-6d8fef56cc16, HandlerErrorCode: GeneralServiceException)
```
原因を確かめるため、以下のような検証作業を行ってみましたが、
問題の解決には至りませんでした。

(作業1)
タスク定義のURIの設定が正しいか確認しました。
nginxコンテナのイメージ URIがlatestになっていなかったので
```
9xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/myapp-prod-nginx
```
を以下に変更し、タスク定義を修正。
```
9xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/myapp-prod-nginx:latest
```
失敗しているサービスを削除し、サービスを再作成したが、同じエラーが発生し解決せず。


(作業2)
下記の記事に記載されている手法で一時的にデプロイサーキットブレーカーをオフにするとエラー時のログを確認。

https://dev.classmethod.jp/articles/tsnote-ecs-deployment-circuit-breaker-created-in-disabled-state/

(結果)
AWSのIAMの権限設定に起因する問題であったことが判明し、問題解決。
key?

# ハッシュのキーを探す
>key?(key)

例に渡された引数と一致しているキーのあるかハッシュを調べる
>Checks the hash for a key matching the argument passed in:
```rb
irb(main):001:0> hash = ActiveSupport::HashWithIndifferentAccess.new
=> {}
irb(main):002:0> hash['key'] = 'value'
=> "value"
irb(main):003:0> hash.key?(:key)
=> true
irb(main):004:0>  hash.key?('key')
=> true
```
別名:`include?, has_key?, member?
>Also aliased as: include?, has_key?, member?

https://api.rubyonrails.org/classes/ActiveSupport/HashWithIndifferentAccess.html#method-i-key-3F

### memberはkey?のエイリアス
>member?(key)Link
Alias for: key?

https://api.rubyonrails.org/classes/ActiveSupport/HashWithIndifferentAccess.html#method-i-member-3F
2025/1/1

# あけましておめでとうございます
### 現状：
エンジニアへの未経験転職。
就職先もほぼ決まり、2月からひよこエンジニアに。

2025年は頑張ろうということで、2025年学習記録1日目。

内容は常に書き散らしのメモです、あしからず。

**当面の目標：LPIC101,102合格**

## `#!/bin/bash`とは？
### 以下、perplexity回答。


- シェルスクリプトの先頭に記述される「シバン」（shebang）と呼ばれる行。

### 意味：

1. このスクリプトがbashシェルで実行されることを指定します[1][2]。
2. スクリプトを実行する際、システムは/bin/bashインタープリターを使用してスクリプトを解釈します[3]。
3. スクリプト内でbash固有の機能を使用できることを明示します[2]。

### 主な特徴：

- スクリプトを./script.shのように直接実行した場合、指定されたインタープリター（この場合はbash）でスクリプトが実行されます[4]。
- bashの拡張機能（配列変数、高度な比較機能など）を使用できます[2]。
- 移植性や永続性が期待できないスクリプトの場合、bashを明示的に指定することで機能を制限せずに書くことができます[2]。

### 注意点：

- #!/bin/shと書いた場合、環境によっては異なるシェル（例：dash）で実行される可能性があるため、bash固有の機能を使用する場合は#!/bin/bashと明示することが重要です[2]。

### Citations:

[1] https://moneyforward-dev.jp/entry/2015/05/21/bash-script-tips/
[2] https://qiita.com/jkr_2255/items/84366f677be3365331cd
[3] https://note.com/milkcoff_e/n/nb645f1dc3f2d
[4] https://nrbm-akatsuki.com/142/
[5] https://tech-blog.rakus.co.jp/entry/20210525/shellscript
[6] https://qiita.com/yn-misaki/items/6fcfab082dd664f10d4e
[7] https://qiita.com/tanimoto-hikari/items/e505b24c5d074b97c3c7
[8] https://zenn.dev/takeo/articles/532898d753b6fc


## インタープリターとは？
プログラムを1行ずつ解釈しながら実行するソフトウェア。


### 以下、コメント
なるほど。
つまり、`#!/bin/bash` とは、外部のパッケージを読み込む記述みたいなもの？
書かずに実行したらどうなる？
＝＞`echo` で呼び出すだけなら記述が無くても何も問題なく実行される。
またどこかのタイミングでやってみるか。


# 配列について
実行権限を与えた`.sh`ファイルで、配列を記述。
`fruits()`という配列があった場合、
`echo ${fruits[@]}`で配列の中身を、
`echo ${fruits[0]}`で`index0`の内容を、
`echo ${!fruits[@]}`で`index`を、
`echo ${#fruits[@]}`で`index`の個数を返してくれる。

この部分は書き方だけで他のプログラミング言語と同じみたい。

配列の追加方法：`fruits[3]='banana'`（例）
配列の削除方法：`unset fruits[3]='banana'`（例）

非常に分かりやすい。


### 引数とは。
実行するとき、シェルに渡す値。`./○○.sh a b` a, b がそれぞれ第一引数、第二引数

### `echo $?` コマンド
直前に実行されたコマンドの戻り値（終了ステータス）を表示するためのコマンド。
成功していたら `0` が返ってくるらしい。

### `read` コマンド
対話式で受け付ける標準入力モード。
- `read -p '入力時に文字を表示させる：' var`
- `read -sp 'シークレットモードでの入力：' password`
- `read -a names` # 配列（Array）での入力




## Python3
- 配列の長さを取得する方法
  `len(array)`
- 今回使用したもの：
  `for i in range(len(array)):`
- Pythonでは、`&&` は論理演算子として使用できない。
　代わりに `and` を論理AND演算子として用いる。





### 今日はここまで！
#20250101

+-------+-------+-------+
|   魚  |   鮭  |   C   |
+-------+-------+-------+
|   1   |   1   |   ○   |
|   2   |   1   |   ×   |
|   1   |   1   |   ○   |
+-------+-------+-------+
列Aと列Bの値が同じなら、oを入力し、違う場合はxを入力




Sub CompareValues()
    ' 変数の宣言
    Dim lastRow As Long
    Dim i As Long
    
    ' エラー処理
    On Error Resume Next
    
    ' 最終行を取得
    lastRow = Cells(Rows.Count, 1).End(xlUp).Row
    
    ' ヘッダー行の作成
    Range("A1").Value = "魚"
    Range("B1").Value = "鮭"
    Range("C1").Value = "判定"
    
    ' 列の幅を自動調整
    Columns("A:C").AutoFit
    
    ' ヘッダーの書式設定
    Range("A1:C1").Font.Bold = True
    With Range("A1:C1")
        .Interior.Color = RGB(200, 200, 200)
        .HorizontalAlignment = xlCenter
    End With
    
    ' 各行の値を比較
    For i = 2 To lastRow
        ' A列とB列の値が同じかチェック
        If Cells(i, 1).Value = Cells(i, 2).Value Then
            Cells(i, 3).Value = "○"
        Else
            Cells(i, 3).Value = "×"
        End If
    Next i
    
    ' 結果の列の中央揃え
    Range("C2:C" & lastRow).HorizontalAlignment = xlCenter
    
    ' 枠線の設定
    With Range("A1:C" & lastRow).Borders
        .LineStyle = xlContinuous
        .Weight = xlThin
    End With
    
    MsgBox "比較が完了しました。", vbInformation
    
    ' エラー処理の終了
    On Error GoTo 0
End Sub
小紅書のエンゲージメント自動化ツール「紅薯養号器」の紹介

中国最大のライフスタイルSNSプラットフォーム「小紅書（RED）」で活動している方々にとって、アカウントの育成は重要な課題です。今回は、その作業を効率化できるChrome拡張機能「紅薯養号器」をご紹介します。
紅薯養号器とは？
紅薯養号器は、小紅書でのアカウント育成を自動化するブラウザ拡張機能です。人間らしい行動パターンでの閲覧、いいね、コレクション、コメントなどの操作を自動化し、アカウントの自然な成長をサポートします。
主な機能
1. カスタマイズ可能な自動操作
投稿の閲覧
いいね
コレクション（ブックマーク）
コメント
フォロー
それぞれのアクションの確率を設定可能
2. AIによるスマートコメント生成
複数のコメントスタイルから選択可能
誠実な称賛スタイル
インタラクティブな質問スタイル
ユーモアスタイル
共感スタイル
情報提供スタイル
3. データ分析と可視化
いいね、コメント、コレクション、フォロー数の追跡
閲覧時間の記録
詳細な統計情報の提供
使い方の3ステップ
設定: アカウントの育成方針に合わせて、各種操作の確率を設定
実行: 自動化タスクを開始し、ツールが設定に従って操作を実行
分析: 育成データを確認し、効果を測定
特徴的な機能
カスタマイズ可能な自動化
異なるニッチに対応できるよう、各操作の確率を細かく設定できます。例えば、10件の投稿を閲覧する中で5件にいいねをつけるといった設定が可能です。
スケジュール機能
定期的な育成作業を自動化し、手作業による負担を軽減します。
データ分析
すべての育成活動のデータを記録し、可視化された形で提供します。これにより、育成戦略の効果を簡単に把握できます。
セキュリティと安全性
人間らしい行動パターンを模倣し、アカウントの安全性を確保
カスタマイズ可能な操作間隔
アクション制限の設定が可能
まとめ
紅薯養号器は、小紅書でのアカウント育成を効率化したい運営者やインフルエンサーにとって、非常に有用なツールです。特にAIによるコメント生成機能は、エンゲージメントの質を保ちながら作業を自動化できる点で注目に値します。
インストール方法
Chrome ウェブストアから直接インストールできます：
[Chrome ウェブストア - 紅薯養号器](https://chromewebstore.google.com/detail/%E7%BA%A2%E8%96%AF%E5%85%BB%E5%8F%B7%E5%99%A8-%E5%B0%8F%E7%BA%A2%E4%B9%A6%E4%B8%80%E9%94%AE%E8%87%AA%E5%8A%A8%E5%85%BB%E5%8F%B7%EF%BC%8C%E6%B5%81%E9%87%8F%E6%BB%9A%E6%BB%9A%E6%9D%A5/abbnjgmnjeidchddihllfjjaogbdommm)
[紅薯養号器Homepage](https://yanghao.app)
【Go言語】継承と埋め込み

### はじめに
Go言語を学習しはじめて、他言語の継承のようなことをしたい場合にどのように書くべきかわからなかったため調査しました。

### 継承の目的
継承とは、既存クラスやオブジェクトであるスーパークラス（親クラス）から、サブクラス（子クラス）に、クラスの属性や振る舞いといった特性を受け継ぐをことです。

継承は下記２点の目的を達するための仕組みであると考えられます。

1. **コードの再利用**
2. **多態性の実現（柔軟に拡張可能な設計）**

コードの再利用は、共通の機能を持つクラスが必要な場合に、親クラスを継承した子クラスを作成することで、既存のコードを **再利用** できます。また、複数のクラスで共通の特徴がある場合に、抽出して親クラスにまとめること（**汎化**）でも、コードの再利用に繋がり、効率的な開発ができます。

多態性とは同じ操作をしたときに、異なるオブジェクトで異なる振る舞いをすることです。これにより、柔軟に拡張可能なシステムにすることができます。

https://qiita.com/dsudo/items/24aa4b6b30f1651e2f4a

### Go言語に継承がない理由は？

Go言語では言語仕様として継承はありません。
設計段階で継承による複雑さを回避するために採用しなかったようです。

言語に関わらず、継承の問題点はよく議論に上がっていると思います。「初めてのGo言語」でも、「クラス継承よりオブジェクト合成の方がよい」と主張されていました。

継承では基底クラスと派生クラスの結合度が高くなってしまいますし、派生クラスは基底クラスに依存することでカプセル化を破ることにもなります。そのため、派生クラスは基底クラスの実装を正しく理解した上で実装しないとバグを埋め込んでしまうことになります。

こうした継承の問題点を回避するために、Goでは言語仕様で継承をサポートせずに、継承で実現したかった **「再利用」は埋め込み（embedded field）による委譲** 、**「多態性」はinterface** 、で実現します。

https://qiita.com/AkitoTsukahara/items/8d2e1414c3e2e14d462a

https://qiita.com/sonatard/items/2b4b70694fd680f6297c

### Go言語でのコードの再利用

Go言語では継承がないが、合成（composition）や昇格（promotion）が組み込まれており、これらを使うコードの再利用が推奨されています。

埋め込みフィールドとして埋め込むことで、フィールドやメソッドは埋め込んでいる上位の構造体に「昇格」し、その構造体から直接呼び出しが可能になります。構造体に埋め込めるのは構造体だけでなく、どのような型でも可能です。

ただし、埋め込みフィールドと同名のフィールドがある場合は、埋め込まれる側が隠れてしまうのでアクセス時に型を明示する必要があります。

### 継承と埋め込みの違い

埋め込みにより継承と似たようなことができるだろうと考えていたためにハマりました。

継承ではスーパークラスを期待する関数にサブクラスを渡すことができるが、埋め込みで同じフィールドを持つ構造体でも、同様のことを行うことはできません。またGoの具象型には動的ディスパッチがないため、埋め込まれた構造体が埋め込まれていることを知ることができないです。

例えば、埋め込む側（Outer）と、埋め込まれる側（Inner）があり同名のメソッドがあったとします。このときにInner側のメソッドから同名メソッドを呼び出しても上位（Outer）のメソッドを呼び出すことができません。

**検証コード**

```go
func main() {
	outerA := &OuterA{
		Inner: Inner{name: "Hoge"},
	}

	fmt.Printf("%s \n", outerA.getName()) // OuterA
	fmt.Printf("%s \n", outerA.greet())   // Hello : Inner
}

type Inner struct {
	name string
}

func (i *Inner) greet() string {
	return "Hello : " + i.getName()
}

func (i *Inner) getName() string {
	return "Inner"
}

type OuterA struct {
	Inner
}

func (o *OuterA) getName() string {
	return "OuterA"
}
```
継承の感覚で、7行目で「outerA.greet()」で呼び出したときに、Outer側でオーバーライドしているgetName()が呼ばれて「Hello : OuterA」と出力されるつもりでいました。

この挙動はGo言語の埋め込み（embedded field）は継承ではなく委譲を実現する仕組みのため、このような挙動になります。他言語の継承のようなこと（再利用ではなく多態性）を実現するためには埋め込みではなく、インターフェースで実現する必要があります。

今まで継承（+オーバーライド）で実現していたようにOuter側のgreet()を呼び出したときにOuter（上位）のメソッドを呼ぶには下記のようにインターフェースを利用すれば実現は可能です（「これで本当に良いのか？」という気持ちでいます…もっと良い方法があれば知りたい）

```go
type Namer interface {
	getName() string
}

func (i *Inner) greet(n Namer) string {
	return "Hello : " + n.getName()
}

func main() {
	outerA := &OuterA{
		Inner: Inner{
			name: "Hoge",
		},
	}

	fmt.Printf("%s \n", outerA.greet(outerA)) // Hello : OuterA 
}
```

### まとめ

他言語で継承によって実現していた目的はGo言語では下記の機能で実現します。

1. 実装の再利用 → 埋め込み（embedded field）
2. 多態性 → Interface

Go言語では設計段階で両者を明確に分けることで、設計上の問題が起きないように工夫されていることがわかりました。実現したい目的をしっかりと考えながら適切な方法を選択してシステム設計していくことで、より品質の高いシステムに繋がると思いました。

### 参考文献
https://qiita.com/Maki-Daisuke/items/511b8989e528f7c70f80

https://zenn.dev/kanatakita/articles/9cb1e7a043b7a2784bf9
converted_arrays

# `@converted_arrays`がnillかfalseであれば新しくSetクラスを生成する
```rb
    def converted_arrays
      @converted_arrays ||= Set.new
    end
```
https://github.com/rails/rails/blob/9ab2d030209d9608a6c866d83210f5b3b7d2319e/actionpack/lib/action_controller/metal/strong_parameters.rb#L197C1-L199C8

#### Set　数学で使う集合を扱うクラス
https://qiita.com/masatom86650860/items/f3ab6b64f9aebecf218a

#### ||= どちらもfalseであれば代入される
https://qiita.com/masatom86650860/items/424c45935529e965be84
ゲームボーイ RGBDS 開発メモ 第8回 チュートリアルを読んでいく (Function)

チュートリアルを読みすすめていきます。

[https://gbdev.io/gb-asm-tutorial/part2/functions.html](https://gbdev.io/gb-asm-tutorial/part2/functions.html)

### Function

やっと関数です。引数のような概念はなく、レジスタに必要なものをいれて呼び出します。

```
; Copy bytes from one area to another.
; @param de: Source
; @param hl: Destination
; @param bc: Length
Memcopy:
    ld a, [de]
    ld [hli], a
    inc de
    dec bc
    ld a, b
    or a, c
    jp nz, Memcopy
    ret
```

いままで、タイルなどのコピーのルーチンがすべてベタ書きでしたが、これでまとめられます。

`ret` で呼び出した側に戻ります。

```
    ; Copy the tile data
    ld de, Tiles
    ld hl, $9000
    ld bc, TilesEnd - Tiles
    call Memcopy
```

callで呼ぶだけです。条件付きcallもあるみたい。

### 次回

次回はコントローラの値を取得します！
Setクラス

# 数学で使う集合を扱うクラス

>クラス・モジュールの継承リスト: 
`BasicObject>Kernel>Object>Enumerable>Set` 
要約
`集合`を表すクラスです。`要素の間に順序関係はありません`。
```rb
>new(enum = nil) -> Set
new(enum = nil) {|o| ... } -> Set
```
>`引数 enum で与えられた要素`を元に、新しい集合を作ります。

>引数を指定しない場合、または引数が nil である場合には、`空の集合を作ります`。

>引数を与えてブロックを与えない場合、`enum の各要素からなる集合を作ります`。

>引数とブロックの両方を与えた場合、enum の各要素についてブロックを評価し、その結果を新しい集合の要素とします。

>[PARAM] enum:
`集合要素を格納するオブジェクトを指定`します。 `enum には each メソッドが定義されている必要`があります。
[EXCEPTION] ArgumentError:
引数 enum が与えられて、かつenumに `eachメソッドが定義されていない`場合に発生します。

```rb
irb(main):020:0> p Set.new
#<Set: {}>
=> #<Set: {}>
irb(main):021:0> p Set.new([1, 2])
#<Set: {1, 2}>
=> #<Set: {1, 2}>
irb(main):022:0> p Set.new([1, 2]) {|o| o * 2}
#<Set: {2, 4}>
=> #<Set: {2, 4}>
irb(main):023:0> require 'set'
=> false
irb(main):024:0> p Set.new
#<Set: {}>
=> #<Set: {}>
```

https://docs.ruby-lang.org/ja/latest/class/Set.html

#### ハッシュも試してみた
```rb
irb(main):030:0> a = Set.new({1=>"a", 2=>"b", 3=>["c"]})
=> #<Set: {[1, "a"], [2, "b"], [3, ["c"]]}>
irb(main):031:0> a.size
=> 3
irb(main):032:0> a[1]
(irb):32:in `<main>': undefined method `[]' for #<Set: {[1, "a"], [2, "b"], [3, ["c"]]}> (NoMethodError)

a[1]
 ^^^
irb(main):033:0> a
=> #<Set: {[1, "a"], [2, "b"], [3, ["c"]]}>
irb(main):034:0> a.first
=> [1, "a"]
```
指定方法はわからないが、firstで指定できた

#### 二つの集合の共通要素が取得できる。　
>self & enum -> Set
共通部分、すなわち、2つの集合のいずれにも属するすべての要素からなる新しい集合を作ります。

>[PARAM] enum:
each メソッドが定義されたオブジェクトを指定します。
[EXCEPTION] ArgumentError:
引数 enum に each メソッドが定義されていない場合に発生します。

```rb
irb(main):045:0> s1 = Set[10, 20, 30]
=> #<Set: {10, 20, 30}>
irb(main):046:0> s2 = Set[10, 30, 50]
=> #<Set: {10, 30, 50}>
irb(main):047:0> p s1 & s2
#<Set: {10, 30}>
=> #<Set: {10, 30}>
```

https://docs.ruby-lang.org/ja/latest/class/Set.html
誤差なくTimeSpanを作る

## 参考
この記事は、以下の動画を参考にしています。
詳しくは、動画をご覧ください。

<iframe width="560" height="315" src="https://www.youtube.com/embed/VTLm119vEx0?si=RqEcVU7EDBwST4Cr" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

## .NET 8まで
秒数（など）から`TimeSpan`を作る場合、元となる`double`が誤差を含む可能性があり、`TimeSpan`にも誤差が付いてしまう。

```C#
var time = TimeSpan.FromSeconds(value: 101.832);
Console.WriteLine(time);
// 00:01:41.8319999
```

## .NET 9
`TimeSpan.FromSeconds`には、秒、ミリ秒、マイクロ秒をそれぞれ`long`で指定するオーバーロードが用意されており、誤差なく`TimeSpan`を作ることができる。

```C#
var time = TimeSpan.FromSeconds(seconds: 101, milliseconds: 832);
Console.WriteLine(time);
// 00:01:41.8320000
```

`TimeSpan.FromMinutes`など、他のメソッドにも同様のオーバーロードが用意されている。
【ChatGPT】回答内容の質をレベルで調整するPromptを紹介します。


　どうも、カーブミラーです。
　明けましておめでとうございます。
　本年もよろしくお願いいたします。

　今回は、回答内容の質を、レベルで調整するPromptを紹介します。

:::note info
本記事は、ChatGPT（Plus版）
で行なっております。
画像はありません。あしからず。
:::
　ChatGPT等の動作状況を知らせる
　　OpenAIのステータスページ。
　　　[OpenAIステータス](https://status.openai.com/)
***
　SoraのPlus/Teamユーザーへの
　　クリスマスプレゼント🎁は
　　　現在も有効ですよ😸

　どんどん動画生成しましょうね。
***
　さっそく、【本題】です。

　今回は、
　　回答内容の質を
　　　レベルで調整するPromptを
　　　　紹介します。

　すぐるさんが
　　ポストしてくださいました。
　　　[すぐるさんポスト](https://x.com/SuguruKun_ai/status/1872827973172380074?t=aXlGY2efFR6tQV9vEs6Htg&s=19)

　＊＊＊に必要なことを記述して
　　送信してください。

```Text:回答の質をレベルでコントロールするPrompt
「＊＊＊」について回答してください。

・レベル1：基本的な回答 
・レベル2：より複雑な回答 
・レベル3：よりクリエイティブな回答 
・更に上をいく「レベル4」の回答
```

　なお、
　　このPromptを
　　　一度に使うのではなく、
　　　　欲しいレベルを
　　　　　指定する形の方が
　　　　　　良いようです。

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
データベースのきほん #8-テーブル設計の基礎

こんにちは、4年目エンジニアの nakaSay です。

本記事では「データベースのきほん」という書籍の内容をかい摘み、いくつかのパートに分けて記事を投稿しています。
本書籍は入門書であり、記事では以下のような内容を取り上げる予定です。気になった方は是非気軽にお立ち寄りください。

1. [データベースの全体像](https://qiita.com/nakaSay/items/2bfec4e0b56e2032db40)
1. [リレーショナルデータベースとは](https://qiita.com/nakaSay/items/a154bc026a13b2f9e256)
1. [データベースに関わるお金の話](https://qiita.com/nakaSay/items/d065b52c6fe55ba3070a)
1. [データベースとアーキテクチャ構成](https://qiita.com/nakaSay/items/a96293ce85f7e92766f0)
1. [DBMS を操作するときの基本知識](https://qiita.com/nakaSay/items/2c393f85ecec752390b8)
1. [SQL文の基本](https://qiita.com/nakaSay/items/86c49eec04e6e6748c9e)
1. [トランザクションと同時実行制御](https://qiita.com/nakaSay/items/df1073b0ed73d5389e60)
1. [テーブル設計の基礎](#テーブル設計の基礎)
1. [バックアップとリカバリ](https://qiita.com/nakaSay/items/cd6239ae500594b0784e)

# テーブル設計の基礎
ここでは、RDBにおけるテーブル設計の基礎について説明します。

RDBにおいて、データを管理・保存するための唯一の入れ物は「テーブル」です。
データは様々なものがあるため、何らかの基準を元にテーブルを整理する必要があり、それが「テーブル設計」と呼ばれています。

整理された結果、テーブルは共通の属性を持ったデータの集合となります。
これを表現する言葉に「テーブル名は必ず複数形か集合名詞で表現できる」という格言があり、例えばトマトやレタスなどのデータが格納されていれば「Vegetables」というテーブル名を付けることができます。
そのため、テーブルは「野菜」や「果物」など、現実世界でカテゴライズされている概念や集合を表したものとなります。
なので、現実世界で名前のついていない雑多な集まりはテーブルに存在しません。

## 基本ルール

テーブル設計のアンチパターン（やってはいけないパターン）として以下のようなものがあります。
- 「何でもボックス」のような何の関連性も無いランダムな集合
- 「トマトテーブル」や「レタステーブル」など個々のモノがテーブル階層となる
    - 現実世界の文脈で個々に作りたい場合などは除く

テーブル設計は自由度が高いですが、基本ルールは「最上位の概念集合」にまとめることです。
- 例）「一般会員テーブル」と「プレミア会員テーブル」を作るのではなく、「会員テーブル」にまとめる


## データの一意性
テーブルの「列」は個体の「属性」で、会員テーブルであれば「年齢」や「性別」などが個々の特性として考えられます。
各データは識別できる必要があるため、全ての属性が全く同じというデータは存在してはいけません。
そのため、「必ず主キーを設定する」という大原則があります。
主キーとは一意な識別子で、一般的にはIDを使うことが多いです。
可変であったり重複するものは一意であることを保証できないため、「名前」などを主キーに使うことはできません。

つまり、テーブルとは「一意な識別子を持った共通項によってまとめられたモノの集合」と言えます。

# 正規形
前節では「テーブルとは何か」ということを中心に説明しましたが。次に具体的なテーブル設計のセオリーについて説明します。

テーブル設計において構築された基本的なセオリーに「正規形（Normal Form）」があります。
正規形は第1正規形から第5正規形までありますが、第3正規形まで抑えていれば実務としては十分なレベルです。

## 第1正規形（1NF）
第1正規形の定義は「1つのセルに複合的な値を含んでいない」というものです。

例えば「扶養者」など、複数の値が紐づく場合は別テーブルに分離してカテゴライズすることが必要です。
もし複合的な値を含んでしまう場合、主キーから値を特定することができなくなり一意性を失ってしまいます。

RDBではこの定義に反するテーブルを作ることは技術的に不可能なため、RDBのテーブルは全て自動的にこれを満たしています。

## 第2正規形（2NF）
第2正規形の定義は「部分関数従属を含んでいない」というものです。

テーブル内の各レコードは主キーを持っていて、我々はその値を元に紐づくデータを取得することができます。
つまり、テーブルとは「主キー（入力値）から対応したデータ（出力値）を得る」関数と捉えることができ、この主キーと他の列の間に成立する関数的な一意性のことを関数従属性と呼びます。

主キーは複数列の組み合わせで表現されることもあり、その際に「主キーの一部の値から、一部の列の値を特定できる」場合があります。つまり、部分的に関数従属性が発生しているのですが、これは複数の集合が混ざっている状態といえます。
そのため、それらを分離して適切にカテゴライズすることが必要です。
主キーが1つの列だけで決まる場合は自動的に第2正規形を満たしています。

## 第3正規形（3NF）
第3正規形の定義は「推移関数従属を含んでいない」というものです。

第2正規形では「主キーの一部の値から、一部の列の値を特定できる」場合でしたが、第3正規形では「主キー**以外**の列から、一部の列の値を特定できる」場合を考えます。
主キーから見ると「主キー → 非主キー → 特定の列」と推移しているため、この状態を推移関数従属と呼びます。
この場合も複数の集合が混ざっている状態と言えるため、テーブルを分離することが必要です。

# ER図

正規化を行うと、テーブルが分割されて数が増えていきます。
正規化の目的はあくまで「更新異常」のリスクをなくすことが目的なのですが、結果としてテーブルの数が増えるのも事実です。
複雑な業務システムであれば、テーブルの数は軽く数百に達します。
そうなってくると人間の能力で全てのテーブルの関係性を把握することが難しいため、ER図（Entity-Relationship Diagram）と呼ばれるテーブル間の関連性を一望することができる技術が存在します。
https://www.ntt.com/business/services/rink/knowledge/archive_58.html

# まとめ
- テーブルとは集合である
- テーブルとは関数である
- 上の2つを覚えておけばテーブル設計は終わったも同然である
- それでも不安な人は、「第2正規形」と「第3正規形」のルールだけ覚えておくと良い
- 増えたテーブルは「ER図」を描いて整理すると良い

## 参考

https://www.shoeisha.co.jp/book/detail/9784798135168
探索的データ分析（EDA）の実践：ステップバイステップで学ぶ方法と活用ポイント

データ分析コンペティションに参加する際、探索的データ分析（EDA）は成功のカギを握る重要なプロセスです。この記事では、テーブルデータを使ったコンペティションを想定して、EDAの具体的な手順とその結果から何を読み取るべきかを分かりやすく解説します。

---

## **1. EDAの目的とは？**

EDA（探索的データ分析）は、データの性質を理解し、分析やモデル構築の方針を決めるための準備段階です。EDAを行うことで以下のことが可能になります：
- データ全体の特徴を把握する
- 欠損値や外れ値を発見する
- 目的変数（予測したい値）と特徴量の関係性を理解する
- 必要なデータクリーニングや加工方法を考える

---

## **2. 実際のデータ例**

今回の例として、家の価格予測コンペティションを考えます。このデータには、各家の特徴（部屋数、広さ、築年数など）と価格（目的変数）が含まれています。

### **データの例**
| ID   | 部屋数 | 広さ（㎡） | 築年数 | 地域      | 価格（目的変数） |
|------|--------|------------|--------|-----------|------------------|
| 1    | 3      | 80         | 15     | 都心      | 5000             |
| 2    | 4      | 100        | 10     | 郊外      | 3000             |
| 3    | 2      | 60         | 30     | 地方      | 1500             |

---

## **3. ステップバイステップで進めるEDA**

### **ステップ 1: データの基本情報を確認**
まずはデータの基本構造を把握します。
- **列名**（特徴量と目的変数）を確認
- 各列のデータ型（数値型、カテゴリ型など）を把握
- データに欠損値や外れ値がないか調べる

#### **具体例**
- 築年数に欠損値が10% → 平均値や中央値で埋める必要がある。
- データサンプル数が少ない場合、モデリングの前にデータ拡張を考える。

---

### **ステップ 2: 目的変数（価格）の分布を確認**
目的変数（価格）がどのような分布をしているかを確認します。

- **確認ポイント**：
  - 正規分布に近いか、それとも偏っているか？
  - 異常に高い値や低い値（外れ値）がないか？

#### **具体例**
価格が右に偏っている（高い価格帯が多い）場合は、対数変換（log変換）を適用して正規分布に近づけることが検討されます。

---

### **ステップ 3: 特徴量の分布を調べる**
各特徴量の分布を確認して、どのような情報を含んでいるかを調べます。

- **ヒストグラムや箱ひげ図**を使い、データの範囲やばらつきを視覚化。
- 外れ値がある場合は、その影響を考慮します。

#### **具体例**
- 築年数が異常に高い（例: 築150年など）データが見つかった場合、これは削除または修正が必要。

---

### **ステップ 4: 特徴量間の関係を分析**
特徴量同士や目的変数との相関関係を調べます。

- **相関係数**を計算し、価格に強く影響する特徴量を特定。
- 特徴量同士に高い相関がある場合、冗長な情報を整理。

#### **具体例**
- 「広さ（㎡）」と価格の相関が+0.8 → 広さは価格を決める重要な要素。
- 「部屋数」と価格の相関が+0.3 → 部屋数単体では価格に影響が少ない。

---

### **ステップ 5: カテゴリ変数の分析**
文字データ（例: 地域）を分析し、価格にどれほど影響を与えるか確認します。

- カテゴリごとのデータ数や平均価格を比較。
- モデルに利用する場合は「ダミー変数化」が必要。

#### **具体例**
地域ごとの平均価格が以下のような結果だった場合：
- 都心：5000万円
- 郊外：3000万円
- 地方：1500万円

この結果から、地域は価格に大きな影響を与える重要な特徴量だと判断できます。

---

### **ステップ 6: 問題点を特定して対処法を考える**
EDAで得られた情報を元に、以下のような問題点と対処法を整理します。

#### **具体例**
1. **欠損値**:
   - 築年数の欠損値を中央値で埋める。
2. **外れ値**:
   - 異常に高い広さ（例: 1000㎡以上）のデータを削除。
3. **特徴量の加工**:
   - 広さ（㎡）と部屋数を組み合わせて「1部屋あたりの広さ」を新たな特徴量として作成。

---

## **4. EDAの結果から読み取れること**

EDAの結果を基に、以下のような洞察が得られます：

1. **重要な特徴量**:
   - 「広さ（㎡）」「地域」「築年数」は価格に大きな影響を与えるため、モデルに取り入れるべき。
2. **データの問題点**:
   - 欠損値や外れ値をクリーニングする必要がある。
3. **データの偏り**:
   - 価格の分布が偏っているため、対数変換が効果的。
4. **次のステップ**:
   - 特徴量エンジニアリングやデータクリーニングを進める。

---

## **5. まとめと次のアクション**

EDAはデータ分析プロジェクトの基礎を築く重要なプロセスです。この例では、家の価格を予測するために以下を実施しました：
- データの全体像を把握
- 目的変数と特徴量の関係性を分析
- 欠損値や外れ値を発見し、対処法を検討

次のステップでは、EDAの結果を元に特徴量の加工やモデル構築に進みます。分析の精度を高めるために、丁寧にEDAを進めることが成功のカギです！
2025年の抱負

## はじめに　
大学3年生の実務経験半年の駆け出しエンジニアです。今回も振り返りと抱負を書こうと思います。

 ## 2024年の振り返り
怒涛のエンジニア祭りでした。これまでは独学でエンジニアの勉強をしてきたため成長も感じずにいました。
しかし、2024年はハッカソンに3度参加し、長期インターンの仕事に勤め半年ほど経ちました。3月までにインターンに参加はできませんでしたが、今のインターン先ではとても刺激になる環境で仕事できているので後悔はしていません。本当に感謝しきれません。


## 2025年の抱負と確実に達成すること
抱負
- 就職する前の準備
内定をいただいてからもスタート、就職してからもスタートだと思っています。働き始めて最速で開発をリードできるエンジニアになるため、今からできることをやろうと思います。具体的にいまも初めていることですが、エンジニアが読むべき良書を読むこと、使ってる技術に触れることです。

- ユーザーのいるアプリを作る・ユーザーを作る！
ユーザーと自分の考えのギャップを知ることが成長につながると感じるからです。ユーザーファーストなアプリを作りたいとは思ってはいるものの自分の思っているユーザーファーストは本当にユーザーファーストなのかというところを突き詰めていきたいですね。

- 学生生活でしかできないこともしっかり堪能する！

最後に
この度また、やる気を引き出すために投稿をしてみました。これからもジャンジャン投稿していきたいと思いますし、社会人になった暁には登壇なんてものをしてみたいと考えています。
1月1日でも勉強！コード書く！変な人でいつづけたいです笑
Linux mint ただのマウント忘れ。ついでに毎日 Windows側の大切なフォルダを毎日バックアップ。

# Linux mintマウント忘れ解消
HDDをラズパイのUSBのようにマウントすればよいのを忘れていた。以下手順。
１．Diskの状態を確認
```
sudo fdisk -l
```
/dev/sdb1 1tb　/dev/sdb2　1tb　と見える。

２．UUIDを表示＆コピー
```
sudo blkid /dev/sdb1
sudo blkid /dev/sdb1
```
３．マウント先を作成
```
mkdir media
mkdir media/disk1
mkdir media/disk2
sudo chmod 777  media/disk1
sudo chmod 777  media/disk2
```
４．マウント
```
sudo vim /etc/fstab
```
中身は以下を追加　コピーしたUUID　を貼り付け。
```
UUID=xxxxxxxxxxxxxx /media/sdb1 ext4 defaults 0 0
UUID=xxxxxxxxxxxxxx /media/sdb2 ext4 defaults 0 0
```

５．リプートで マウントされたことがわかる。当方のマシンでは　ディスクトップに表示される。
```
df -h
```
６．samba設定し直し
```
sudo vim /etc/samba/smb.conf
```
中身を以下で変更
```
[mint_disk1]
   path = /media/disk1
   available = yes
   read only = no
   browsable = yes
   public = yes
   writable = yes
   quest ok = no
 [mint_disk2]
   path = /media/disk2
   available = yes
   read only = no
   browsable = yes
   public = yes
   writable = yes
   quest ok = no  
```
   以下を実行
```
sudo systemctl reload smbd.service
sudo systemctl restart smbd.service
```

# Windows側の大切なフォルダを毎日バックアップ
前提はWindows側でネットワークドライブの割り当てがされていること。
１．バッチファイルを c:\bat\backup.batで作成　バックスラッシュは｛￥｝で読み替えてね。
タスクスケジューラで実行の為、ドライブ割当、削除記述追加。
sambaで共有しているので　少してこづりました。　以下サイトが大変参考になりました。
https://qiita.com/t13801206/items/84cb3b9d1a7bc879591e

```
@echo off

rem コピー元フォルダ
set src1="C:\大事なフォルダ１"
set src2="C:\大事なフォルダ２"

rem コピー先フォルダ samba共有名指定
set dst="\\192.168.xxx.xxx\samba_share"
net use %dst%
set dst1="\\192.168.XXX.XXX\samba_share\大事なフォルダ１"
set dst2="\\192.168.XXX.XXX\samba_share\大事なフォルダ２"

rem log file フォルダ
set logfolder="C:\log"
set logfile1=%logfolder%"\robocopy1_%date:~0,4%-%date:~5,2%-%date:~8,2%.log"
set logfile2=%logfolder%"\robocopy2_%date:~0,4%-%date:~5,2%-%date:~8,2%.log"

robocopy.exe "%src1%" "%dst1%" /MIR /LOG+:"%logfile1%" /COPY:DAT /R:3 /W:3
robocopy.exe "%src2%" "%dst2%" /MIR /LOG+:"%logfile2%" /COPY:DAT /R:3 /W:3

net use %dst% /delete
```
２．スケジュール登録して完了

全然関係ない話ですが　GalaryUtility　は　free版で　Windows11pc　パフォーマンス向上しますね。
そんな気がした。
split

# デフォルトで`$;`はスペースが入り、それを基準に分割される文字列を分割する
```rb
split(field_sep = $;, limit = 0) → array
split(field_sep = $;, limit = 0) {|substring| ... } → self
```
与えられたフィールドセパレーター`field_sep`の発生ごとにselfを割っている結果のselfの部分文字列の配列を返す。
>Returns an array of substrings of `self` that are the result of splitting `self` at each occurrence of the given field separator `field_sep`.

`field_sep`が`$;`の時
>When `field_sep` is `$;`:

もし`$;`が`nil`(`$;`のデフォルト値)ならば、splitは`field_seq`が一つの空白として与えられたように同じように分割が起こる。
>* If `$;` is `nil` (its default value), the split occurs just as if `field_sep` were given as a space character (see below).

もし`$;`は一つの文字列ならば、`field_sep`はその文字列として与えられた場合と同じように分割が行われる。
>* If `$;` is a string, the split occurs just as if `field_sep` were given as that string (see below).

https://docs.ruby-lang.org/en/3.4/String.html#method-i-split:~:text=split(field_sep%20%3D%20%24%3B%2C%20limit,string%20(see%20below)

>nil
常に $; で分割する。 $; も nil の場合は、先頭と末尾の空白を除いたうえで、空白文字列で分割する。

https://docs.ruby-lang.org/ja/latest/method/String/i/split.html#:~:text=nil,%E5%88%97%E3%81%A7%E5%88%86%E5%89%B2%E3%81%99%E3%82%8B%E3%80%82
[備忘録]Docker .dockerignoreを利用する

.dockerignoreを利用するとでビルドコンテキストから任意のファイルやフォルダを除外することができる。利点としてはビルドコンテキストに非常に巨大なサイズのファイルが存在するときに、無視することによって、dockerデーモンに渡すさいの時間を短縮できる。

例えば以下のディレクトリ構成の場合考える。
dir
├ hello.txt
├ foo.txt
├ hoge.txt

ビルドコンテキストにdirを指定している際にhello.txtは渡さないようにするには以下手順
1. ビルドコンテキスト内の任意場所に .dockerignore というファイルを作成する
2. .dockerignore をエディタで開き、渡したくないファイルのファイル名を一行ずつ記載していく。

.dockerignore
```
hello.txt
aaa
bbb
...
```

この状態でimage buildすれば.dockerignoreに記載されたファイルは無視される。
余白調整のためだけに安易にdivタグを増やすな、おじさんとの約束だぞ

## はじめに
始めたばかりのころ、余白やレイアウトを整えるために子要素を持たない`<div>`タグを増やして高さや余白を当てて見た目を調整してしまう、そんな経験はありませんか？ちなみに私はめちゃめちゃ身に覚えがありすぎて、変な汗かきながら執筆しています。でも、今だからこそ言いたい。「余白調整のためだけに安易に`<div>`タグを増やすな」と。

## なぜ増やすべきでないか
経験談ですがこういう事態に繋がることが多かったので
1. 冗長なHTMLが出来上がっていた
    HTMLの構造が複雑になり、可読性が下がります。自分のコードを見返したときに、「これはいったい何のために書いた`<div>`なんだ？」と悩んでいました。
    ちなみに当時の私に「クラス名を`spacer`にする」というレベルの頭もなく、より煩雑なコードになっていました。
    ```
    <div class="spacer"></div>
    <div>
      <h2>素敵な見出し</h2>
      <p>素晴らしいコンテンツの数々</p>
    </div>
    <div>
      <h2>素敵な見出し</h2>
      <p>素晴らしいコンテンツの数々</p>
    </div>
    ```
2. スタイルの挙動が予測しづらい
    不要な`<div>`が増えるとそれだけ影響を与える要素が増えたり、スタイルの適用範囲が分かりづらくなっていきます。結果、CSSを書くのがどんどん難しくなるという事態を招くこともありました。
    たとえばこういうflexの子要素に余白調整の`<div>`が記述されていたら少ししんどいかなと思います。
    ```
    <div>　// display: flexを適用
        <div class="spacer"></div>
        <div>
            <h2>素敵な見出し</h2>
            <p>素晴らしいコンテンツの数々</p>
        </div>
        <div>
            <h2>素敵な見出し</h2>
            <p>素晴らしいコンテンツの数々</p>
        </div>
    </div>
    ```
    
    もちろん絶対にダメということは無くて、使うべきケースもあるかとは思います。たぶん。ただ先述した事態を招くことの方が多かったり、CSSへの苦手意識を生む原因にもなると感じています。そして何より、そもそものHTMLとCSSの役割に反しているためこのようなコードを書くべきではないです。

## HTMLとCSSの役割って？
この記事でこれを一番言いたかったと言っても過言ではない。なに、めんどくさそうだって？あっ、こら待て、逃げるんじゃない。


https://developer.mozilla.org/ja/docs/Learn_web_development/Getting_started/Your_first_website/Creating_the_content#html_%E3%81%A8%E3%81%AF

みんな大好きMDNよると
> HTML は、コンテンツの構造を定義するマークアップ言語です。

とありますね。我々が日夜お世話になっているMDN大明神のこのお言葉を無視してHTMLにコンテンツの構造とは言い難い`<div>`タグ、すなわち私が先ほどから死ぬほど繰り返し叫んでいる「余白調整のためだけの`<div>`タグ」を記述するのはいささか妙な話ではないだろうか。
え、怖い？それは一旦置いといて、じゃあ余白調整はどうするのかというと


https://developer.mozilla.org/ja/docs/Learn_web_development/Getting_started/Your_first_website/Styling_the_content#css_%E3%81%A8%E3%81%AF%E4%BD%95%E3%81%8B

> CSS は、HTML の要素を選択的にスタイルにするために使うものです。

余白調整はこっちなんですね、ええ。私はなんと愚かだったのか。「これはこの用途で使うんやで」と言われているにも関わらずそれを無視した用途で使っていた。そのくせ自分の思ったようにCSSが効かないと、やれCSSは難しすぎるだのやれ人類には早すぎたなどと、自身を全く顧みず他責にばかり走っていた。~~実際難しくはあるんじゃないかと今でも思っている。~~

https://html.spec.whatwg.org/multipage/dom.html#semantics-2

> HTML conveys meaning, rather than presentation

そしてこれでもかと言わんばかりにまた他所から引用してくるんですが、ここでもHTMLは意味を伝えるものであって表現をするものではないとも言われていますね。

つまりHTMLはあくまでもコンテンツの内容や構造を表すものであって、それを見やすくするレイアウトや余白についてはCSSに寄せるべきということです。

## まとめ
レイアウトや余白調整をHTML側に寄せるか、CSS側に寄せるかということでどちらも実装はできます。できるんですが、そもそもの決まり事に則っていない方法でやってたら、そりゃあどこかに皺寄せ（私の場合は管理が面倒になったのとCSSが書きにくくなったこと）は来ますよね。

いきなり厳密なタグの使い分けとかはハードルが高いですが、このあたりの言語としての原則、つまり余白調整などの見た目に関するものの責任をHTMLへは寄せずに書いていきたいですねっていうお話でした。

## 参考
- https://developer.mozilla.org/ja/docs/Learn_web_development/Getting_started/Your_first_website/Creating_the_content#html_%E3%81%A8%E3%81%AF
- https://developer.mozilla.org/ja/docs/Learn_web_development/Getting_started/Your_first_website/Creating_the_content#html_%E3%81%A8%E3%81%AF
- https://html.spec.whatwg.org/multipage/dom.html#semantics-2
Apache Flexで領域をドラッグ＆ドロップで変更する

# はじめに

Apache Flexのmx:VDividedBox、mx:HDividedBoxの使い方を簡単にまとめます。
領域をドラッグ＆ドロップで変更することで、領域の高さや幅を可変にすることができます。

# 垂直に分割（mx:VDividedBox）

2つの領域の間にドラッグ可能な区切り線が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102121/c0a7598c-132d-7066-09c9-319daf2e6b0e.png)

区切り線をドラッグして変更したい場所まで移動します。
![image4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102121/12725bf8-cd2d-8068-db5c-2429363a1a10.png)

区切り線をドロップすると領域の高さが変更されます。
![image5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102121/58f059e9-0299-9bbc-b576-d70332b6e1e1.png)

```mxml:Main.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                       xmlns:s="library://ns.adobe.com/flex/spark"
                       xmlns:mx="library://ns.adobe.com/flex/mx"
                       width="400" height="300">

    <fx:Style>
        * { 
            font-family: "Meiryo";
        }
    </fx:Style>

    <mx:VDividedBox left="10" top="10" right="10" bottom="10">
        <s:Group width="100%" height="70%">
            <s:TextArea  left="0" top="0" right="0" bottom="0" />
        </s:Group>
        <s:Group width="100%" height="30%">
            <s:TextArea  left="0" top="0" right="0" bottom="0" />
        </s:Group>
    </mx:VDividedBox>
</s:WindowedApplication>
```

# 水平に分割（mx:HDividedBox）

水平に分割する場合も同様です。
Beamerのテーマをカスタマイズする方法

beamerを使ってスライドを作る際に様々なテーマが配布されており、自分好みのものをインストールして扱うことができる。
今までは、ちょっとしたところをいじる際にスライドのソースコードに直接設定していたが、細かい変更部分が多くなると、ソースコードが見づらくなるため、ダウンロードしたテーマのstyファイルを直接編集を行うことで改善したいと思う。

なお、扱うlatexのエンジンとしては`LuaLatex`として進めていく。

# テーマのインストール
今回は[Focus](https://github.com/pcafrica/focus-beamertheme)というシンプルなテーマを例として行う。まずはgithubからcloneを下記で行う。
```
git clone https://github.com/pcafrica/focus-beamertheme
```
# ファイルの移動
インストールしたファイルの中でstyファイルのものをlatexのディレクトに移動させる。ここで、Latexのコマンドラインツールである`kpsewhich`を使うことでディレクトリやパスを確認できる。以下のコマンドでLualatexが参照する検索パスを確認できる。
```
kpsewhich -var-value TEXMFHOME
```
以下のコマンドの出力のフォルダへファイルを移動させる。
```
~/texmf/tex/latex/beamer/beamerthemefocus-modify.sty
```
最終的には以下のような構造になります。
```
~/texmf/tex/latex/beamer/focus-modify$ tree
.
├── beamercolorthemefocus-modify.sty
├── beamerfontthemefocus-modify.sty
├── beamerinnerthemefocus-modify.sty
├── beamerouterthemefocus-modify.sty
└── beamerthemefocus-modify.sty
```
ファイルが認識されているか確認。ファイルのフルパスが表示されれば、LuaLatexが認識できています。
```
kpsewhich "移動したstyファイル名"
```

# ファイルデータベースの更新
ファイルを適切な場所に移動したら、データベースを更新します。
```
texhash ~/texmf
```
これで直接インストールしたstyファイルを編集することでスタイルや自作のブロックなどを追加することができます
GNU/Linuxカーネルのランタイム保護概要  

# なぜ GNU / Linux に注目すべきなのか？

以下は GNU / Linux の市場に関する統計です：

- 47% のプロフェッショナル開発者が Linux ベースのオペレーティングシステムを使用しています。 (Statista)  
- Linux はオペレーティングシステムが判明しているウェブサイトの 39.2% を動かしています。 (W3Techs)  
- Linux はスマートフォンの 85% を動かしています。 (Hayden James)  
- Linux は、3番目に人気のあるデスクトップ OS で、2.09% の市場シェアを持っています。 (Statista)  
- Linux の世界市場規模は、 2027 年までに 156.4 億ドルに達すると予測されています。 (Fortune Business Insights)  
- 世界最速のスーパーコンピュータ 500 台はすべて Linux で動作しています。 (Blackdown)  
- 上位 100 万のウェブサーバーの 96.3% が Linux を使用しています。 (ZDNet)  
- 現在、 600 以上のアクティブな Linux ディストリビューションがあります。 (Tecmint)  

数年前、 Anti-Virus + Firewall + LSM ( SELinux または AppArmor ) が、ほとんどのケースで主な保護手段の組み合わせでした。サーバーソフトウェア市場は少しずつ変化しています。

# 不死の 0-day 幽霊  

[0-day](https://ja.wikipedia.org/wiki/%E3%82%BC%E3%83%AD%E3%83%87%E3%82%A4%E6%94%BB%E6%92%83) は、ソフトウェアやハードウェアに存在する脆弱性で、ベンダーに公開されており、修正プログラムや他のベンダー提供の対策がまだ利用できないものを指します。つまり、ソフトウェアには常に 0-day の問題が存在します。

問題は、どれほど優れたセキュリティチームを持っていても、またはどれほど予算が豊富でも、サーバーが常に 0-day 攻撃の脅威にさらされているということです。そして、 0-day 攻撃が成功すると、攻撃者は必ず rootkit をオペレーティングシステムに植え付けます。この rootkit は、システムを再起動しない限り取り除くことができません。

# ワクチンソリューション - カーネルランタイム保護

0-day は避けられないとすると、どのように防ぐことができるのでしょうか？もし防げないのであれば、それはすべてのセキュリティソフトウェアが無意味になってしまうことを意味します。なぜなら、0-day は脆弱性が公開される前に、どんな保護手段も回避できるからです。

答えはカーネルランタイム保護です。具体的には、これはワクチンのように機能します。ワクチンを注入した後、攻撃パターンは高い確率でブロックされますが、その効果はワクチン製品の品質に依存します。

現在市場にあるワクチン製品は3つだけです。


# 最強の盾 - Grsecurity  

[Grsecurity](https://ja.wikipedia.org/wiki/Grsecurity) は、 Linux カーネルに対する広範なセキュリティ強化機能であり、インテリジェントなアクセス制御、メモリ破損を基にしたエクスプロイト防止、その他の多くのシステム強化を通じて、さまざまなセキュリティ脅威から防御します。

このプロジェクトは過去 23 年間にわたり積極的に開発および維持されてきました。 Grsecurity の商業サポートは Open Source Security , Inc. を通じて提供されています。

現在、 Grsecurity は保護とパフォーマンスの両面でトップクラスです。

# 日本からの光 - 日立 AKO  

AKO は [Additional Kernel Observer](https://ousar.lib.okayama-u.ac.jp/ja/60101) の略で、日立が支援し、 2020 年に論文が公開されました。

AKO は日立の工業安全ソリューションであり、 LKRG がカーネルに焦点を当てているのに対し、 AKO は工業システムの安全ソリューションです。システム呼び出しを監視し、 UID の実行時異常を検出して保護を提供することに専念しています。この方法は、通常の動作からの逸脱が潜在的なセキュリティ脆弱性を示す可能性があるため、工業制御システムに特に適しています。システム呼び出しやユーザー ID を注意深く監視することで、 AKO は不正な活動を検出して対応し、重要な工業基盤施設をサイバー脅威から保護するのに役立ちます。

AKO ソリューションは主に日立独自の産業セキュリティ用に設計されており、より広範なセキュリティ市場向けの汎用製品となるための多くの機能が不足しています。

# コストとセキュリティのバランス - VED  

VED は [Vault Exploit Defense](https://hardenedvault.net/jp/products/ved/) の略で、 2020 年に設立された新しいスタートアップ企業 HardenedVault によって開発されました。

カーネルレベルの保護は長い間、サイバー空間における最も困難な技術の一つとされてきました。 HardenedVault は、実行時の包括的な保護を実現するための革新的な方法を開拓しました。その製品 Vault Exploit Defense (VED) は、通常非常に高い破壊力を持ち、極めて検出が困難な Linux カーネルの既知(N-day)および未知 (0-day) の脆弱性を検出して阻止します。

VED は Linux カーネル向けの実行時保護ソリューションであり、 0day / Nday の脆弱性に対抗し、後期攻撃を検出します。特に重要なのは、「ワクチン」という比喩とは異なり、既に侵害されたホストで VED が実行されている場合、システム内に隠れている rootkit を検出して阻止できることです。つまり、 VED は「ワクチン」であると同時に治療のための「特効薬」となります。

## 結論

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973392/9b8dd70f-635e-8ae1-ced9-4bae87dce079.png)


GNU / Linux の市場規模と普及率の拡大に伴い、サイバーセキュリティの重要性はますます高まっています。特に、 0-day 攻撃の脅威は避けられず、従来の保護手段だけでは不十分です。  

現在、 Grsecurity は最高レベルの保護を提供しており、 Hitachi AKO は工業システム向けに特化したユニークなソリューションです。一方、 HardenedVault の VED は、 0-day / Nday 攻撃への防御と侵害後の検出を兼ね備えた、コストとセキュリティのバランスを取った実用的な選択肢です。  

今後は、システムの要件やコストに応じてこれらのソリューションを適切に選択し、セキュリティ対策を強化していくことが重要です。
完成とは言えないがschemeを公開

## はじめてschemeのインタープリタを作ってみた

使用した言語:  Java 17

## ソースコードの公開先

https://github.com/masa-oss/uika806

## 作成時の苦労話（？）

自分のためのメモとして、こちらに整理してみた。

https://zenn.dev/clazz/books/a752b62f7b5e64

## 感想

２、３０年前にCommon Lispを学び、
数年前にClojureを学び
２０２４年はSchemeを学びました。

３大Lisp系言語は、それなりに特徴がわかった気になりました。
Next.js 15で作るブログサイト：爆速表示を実現する簡単な方法

## はじめに

みなさん、こんにちは！今回は、Next.js 15を使ってブログサイトを爆速化する方法をご紹介します。できるだけシンプルに解説していきます。

この記事は、[私達の記事](https://tech.jugoya.ai/blog/next-js-ssg-optimization)をまとめ直したものです。

## なぜブログを速くする必要があるの？

ブログサイトが遅いと、以下のような問題が起きます：
- 読者がイライラして離脱してしまう
- Googleの検索順位が下がる
- SNSでシェアされにくくなる

## 今回の改善ポイント

私たちのブログサイトには、こんな問題がありました：
- ページの読み込みに約2秒かかっていた
- SNSでシェアした時の表示が良くなかった

## 解決方法：Static Site Generation（SSG）

Next.js 15には「Static Site Generation」という機能があります。これは簡単に言うと、「事前にページを作っておく」機能です。

### 実装のポイント

1. **generateStaticParams**を使う
```javascript
export async function generateStaticParams() {
  const posts = await getPosts();
  return posts.map((post) => ({
    slug: post.slug,
  }));
}
```

2. **dynamicParams**をfalseに設定
```javascript
export const dynamicParams = false;
```

3. Server Componentsを使う
```javascript
export default async function BlogPost({ params }) {
  const post = await getPost(params.slug);
  return <article>{post.content}</article>;
}
```

## 改善結果

この方法を使った結果、驚くべき改善が見られました：
- 読み込み時間が約0.2秒に短縮（90%以上の改善！）
- SNSでシェアした時の表示が綺麗に
- Googleの検索順位が改善される可能性も！

## まとめ

Next.js 15のSSGを使うことで、簡単にブログサイトを高速化できました。特に難しい設定は必要なく、基本的な実装だけで大きな効果が得られます。

より詳しい実装方法や高度な最適化テクニックについては、[元記事](https://tech.jugoya.ai/blog/next-js-ssg-optimization)をご参照ください。

## 参考リンク
- [Next.js 公式ドキュメント](https://nextjs.org/docs)
- [App Router の解説](https://nextjs.org/docs/app)
- [元記事：Next.js 15 App Routerでのブログ最適化](https://tech.jugoya.ai/blog/next-js-ssg-optimization)

## 最後に

ご質問やコメントがありましたら、ぜひコメント欄でお願いします！
Microsoft Entra で 外部ゲストユーザーが招待を受諾したか確認する方法

ニッチなニーズかと思いますが Microsoft Entraで外部ゲストユーザーが招待を受諾したかを確認したい要件があり、確認できた手順をまとめます。

- [方法1 ユーザーごと目視で確認する方法](#方法1-ユーザーごと目視で確認する方法)
- [方法2 ユーザー情報をダウンロード](#方法2-ユーザー情報をダウンロード)
- [方法3 Microsoft Graph PowerShell SDK を使用する](#方法3-microsoft-graph-powershell-sdk-を使用する)
- [参考情報](#参考情報)


# 方法1 ユーザーごと目視で確認する方法

下記手順でユーザー個々に確認することが可能です。

1. Azure ポータルにログインし、[Microsoft Entra ID]を選択
2. [ユーザー]を選択
3. 確認をしたいユーザーを選択
4. [B2B の招待]の[招待の状態]を確認

招待を受諾している場合には[承諾済み]となります。

まだ受諾されていない場合には[保留中の承諾]となります
# 方法2 ユーザー情報をダウンロード

下記手順でcsvファイルにて情報を一括でダウンロードし確認が可能です。

1. Azure ポータルにログインし、[Microsoft Entra ID]を選択
2. [ユーザー]を選択
3. [ユーザー情報のダウンロード]を選択
4. [ダウンロードの開始]を選択
5. 処理が完了するのを待ちます
6. [ファイルの準備ができました。ここをクリックしてダウンロードしてください]を選択
7. ダウンロードされた CSV ファイルの [invitationState]列を確認

受諾している場合には [Accepted]、まだ受諾されていない場合には[PendingAcceptance]となります。

# 方法3 Microsoft Graph PowerShell SDK を使用する

コマンドで取得する場合には下記になります。

1. 下記Microsoftの公開情報を参照し Microsoft Graph PowerShell とベータ モジュールをインストールします

    [Install the Microsoft Graph PowerShell SDK | Microsoft Learn](https://learn.microsoft.com/ja-jp/powershell/microsoftgraph/installation?view=graph-powershell-1.0)

    **注** 2025 年 1 月 1 日時点では Microsoft.Graph.Beta でないと適切に情報の取得ができません。
    その為、ベータ モジュールもあわせてインストールをしてください。

2. PowerShellを起動します
3. 下記コマンドレットを実行します
    ~~~
    Connect-MgGraph -Scopes "User.Read.All"
     ~~~
 <!---
    Connect-MgGraph -Scopes -TenantID テナントID "User.Read.All"
    -->
4. 資格情報を入力しログインします
5. 以下のコマンドレットを実行します
    ~~~
    Get-MgBetaUser -Filter "UserType eq 'Guest'" | Select-Object DisplayName, ExternalUserState
    ~~~
6. 出力された結果の[ExternalUserState]を確認します

受諾している場合には [Accepted]、まだ受諾されていない場合には[PendingAcceptance]となります。

~~~~
DisplayName ExternalUserState
----------- -----------------
User1    Accepted
User2    PendingAcceptance
~~~~

# 参考情報

[Get-MgBetaUser (Microsoft.Graph.Beta.Users) | Microsoft Learn](https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.beta.users/get-mgbetauser?view=graph-powershell-beta)

[最終サインイン日時を一括で取得する方法 | Japan Azure Identity Support Blog](https://jpazureid.github.io/blog/azure-active-directory/azure-ad-get-lastSignInDateTime/)
自律施工技術開発基盤OPERAを試してみる（ROS2 launchファイルから動かしてみる編）

# 1. はじめに
前回の記事[[1]](#参考記事やサイト)では自律施工技術開発基盤OPERAのリポジトリで公開されているサンプルファイルにて、ROS2 topicを投げて建機を動かしてみることに成功しました。そしてその記事の中で「次回はREADMEでも紹介されているunity用launchファイルから動かす方法を試してみたい」と述べましたので、それに取り組んでみたのが、この記事の内容になります。

なお、この記事のシミュレーション環境は前回の記事[[1]](#参考記事やサイト)で構築した内容となります。このことを前提に記事を記載していきます（つまり細かいことは省きます）。

# 2. 実行環境
- CPU: CORE i7 7th Gen
- メモリ: 32GB
- GPU: GeForce RTX 2070
- OS: Ubuntu22.04(WSL2ではなくPCに直接インストール)
- ROS2: Humble

# 3. シミュレーション環境
シミュレーション環境は前回の記事[[1]](#参考記事やサイト)で構築した以下の環境をベースとします。

https://github.com/pwri-opera/OperaSim-PhysX

そして、前回作成したワークスペースの"/Opera_test"に、以下で公開されている"OPERA 対応油圧ショベル zx200 の土木研究所公開 ROS2 パッケージ群"のリポジトリをクローンして構築していきます。

https://github.com/pwri-opera/zx200_ros2

👆のリポジトリのREADMEを参考に、以下のコマンドでクローンや関連パッケージのインストールやビルドをしました。
```:terminal
source /opt/ros/humble/setup.bash
cd ~/Opera_test/src
git clone https://github.com/pwri-opera/zx200_ros2.git
sudo apt update
sudo apt install python3-rosdep2 
rosdep update
rosdep install -i --from-path src --rosdistro humble -y 
colcon build
source ~/Opera_test/install/setup.bash
```

# 4. シミュレーション結果
まずUnityでAsset/Scenes/SampleScene.unityを開きます。
そして、ROS-TCP-Connectorの設定について、"Robotics" > "ROS Setting"の順でクリックして出てきた画面の"Protocol"のところを"ROS1"->"ROS2"に変更します。そのほかの設定はそのままとしました。

![ROS2Set.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/26c4ede6-1b2d-d935-085f-ffe57bcf15ac.png)

そしてUnityの再生ボタンをクリックしてシミュレーションを開始します。

次にターミナルを開き以下のコマンドを入力し、ROS2とUnityの連携を開始します。
なお、以下のコマンドで出てくる"/Opera_test"は私が設定したワークスペースの名前なので、環境によって変える必要があります。
```:terminal(1)
source ~/Opera_test/install/setup.bash
ros2 launch ros_tcp_endpoint endpoint.py
```

次に以下のlaunchファイルを実行し、rviz2を起動します。
```:terminal(2)
source ~/Opera_test/install/setup.bash
roslaunch zx120_unity zx120_standby.launch
```

このlaunchファイルを実行したときのrviz2の画面は以下です。

![Screenshot from 2024-12-28 09-34-25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/3701af23-a1e3-9cc9-4f76-33b2f378a2d1.png)

**ちなみにこの状態で以下のコマンドでROS2 topicのメッセージを送信しても、zx120_standby.launchファイルによって別のROS2 topicメッセージが投げられていて「メッセージが上書きされる」ような状態なので、油圧ショベルのアームは動きません。**

```:terminal(3)
source ~/Opera_test/install/setup.bash
ros2 topic pub /zx120/arm/cmd std_msgs/Float64 "data: 0.2"
```
そのため、以下の動画のようにrviz2上で角度を指定して"Execute"ボタンを押すことで油圧ショベルのアームを動かすことができます。ただ、動かし方が私もまだよくわかっておりませんので、現時点ではまずとりあえず動かしてみたという段階です。

<iframe width="560" height="315" src="https://www.youtube.com/embed/yWQVZSZww2w?si=FcI0fsrhNP4MBFfe" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

# 5. まとめ
今回は国立研究開発法人の土木研究所 技術推進本部 先端技術チームがgithubで公開している自律施工技術開発基盤OPERAのサンプルファイル内の建機をROS2 launchファイルから動かすことに成功しました。

今後はクローラダンプや他の建機も動かせるかや、土砂の粒子シミュレーションについても試していきたいと考えています。

# 参考記事やサイト
[1][自律施工技術開発基盤OPERAを試してみる（ROS2 topicから動かしてみる編）](https://qiita.com/bebebefu/items/f790dfd744868556a57c)
Youtubeのチャンネル内の動画を取得したとき、shorts動画を判別する方法

判別したいチャンネル内の動画がそんなになければ、
１つずつリダイレクトチェック
youtube.com/shorts/***
でリダイレクトされる場合は通常動画
リダイレクトされない場合はshorts動画という判定もあるけど、
動画の数が多いと、リダイレクトチェックに時間がかかって、
GASだとタイムアウトが発生する問題があった。
なので、
海外フォーラムで調べてみると、
非公式の方法ながら、Shorts動画のプレイリストが
ほぼどのチャンネルも自動生成されていることがわかった。
そこで、
UU~~~から始まるプレイリストIDを
UUSH~~~に編集し、
プレイリスト内の動画IDの配列を取得し、
配列の差分を取得することで、
通常動画の動画ID配列を作り、
その配列で情報取得をすることで、
一気に再生数やいいね数を調べることができた。
以下スクリプト

```js
function getVideoInfo() {
  const s = SpreadsheetApp.getActiveSpreadsheet();
  const ss = s.getSheetByName("getVideoInfo");

  //D2には調べたいチャンネルの投稿動画プレイリストIDが入ってる
  const listId = ss.getRange("D2").getValue();
  const videoIds = getVideoIds(listId);
  console.log(videoIds.length);

  //E2にはスプレッドシートの関数でUUをUUSHに変更したIDが入ってる
  const shortsPlaylistId = ss.getRange("E2").getValue();
  const shortsIds = getVideoIds(shortsPlaylistId);
  console.log(shortsIds.length);

  const diffIds = videoIds.filter(x => !shortsIds.includes(x));
  console.log(diffIds.length);

  const videos = getVideos(sliceByNumber(diffIds, 50));

  var outputArray = [];
  for(var i=0;videos.length>i;i++){
    var url = `https://www.youtube.com/watch?v=${videos[i].id}`;
    var fDate = Utilities.formatDate(new Date(videos[i].snippet.publishedAt) , "JST" , "yyyy/MM/dd");
    var title = videos[i].snippet.title;
    var viewCount = videos[i].statistics.viewCount;
    l(`[${i}]動画名: ${title}, 再生数： ${viewCount}`);//確認用
    //動画データを配列へPUSH
    outputArray.push([title, url, fDate, viewCount]);
  }
  var writeTargetRow = 5;//←書き込みを開始したい行
  ss.getRange(writeTargetRow,2,ss.getLastRow(),4).clear();
  ss.getRange(writeTargetRow,2,outputArray.length,4).setValues(outputArray);

}
```
1日で自分のウェブサイトを作る方法（全部無料）

# こんな人におすすめ

- 「HTML/CSSを概要レベルでは知ってるけど、何も作ったことがない…。」
- 「今日1日暇だから、勉強進めて個人のウェブサイトまで作ってみよ！」
- 「せっかくだし、人に見せられる作成物レベルまで持っていきたい！」
- 「でも、お金はかけたくない…。お金ない…。」

# 完成品

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780099/86789311-14ac-8fa4-0095-1354da62306e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780099/c95291da-aa3a-8627-8459-b01cea056b67.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780099/25f7f111-6996-7b3e-5685-b23915707f47.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780099/117eb303-3c52-5445-dfb3-48a692553144.png)

URL貼るか迷ったのですが、セキュリティの心配もあるのでスクショで。
写真は自前です。
地図は知り合いのコーヒー屋さんを拝借。

# 手順

### 1 . ドメイン名を取得　所要時間：10分

お名前.comを使用しました。1年間無料で使用できます。

https://www.onamae.com/campaign/lp/top/?utm_source=Google&utm_medium=paidsearch&banner_id=102_kwt_domain_domainbrand-onamae_rsa_012&waad=oHo0Fp0R

＊レンタルサーバーをセットでおすすめしてきますがスルーします。

### 2 .  サーバーをレンタル　所要時間：30分

xreaを使用しました。広告表示されますが、無料で使用できます。
このレンタルサーバーにお名前.comで取得したドメインを紐づけます。

https://www.xrea.com/

＊ドメインをセットでおすすめしてきますがスルーします。



### 3 . HTML/CSSファイルを作成　所要時間：3時間〜

下記サイトとコードを参考に、ファイルを作成しました。

https://code-jump.com/profile-menu/


コーディング・ファイル作成は、PC上のVScodeで行っています。
HTMLは130行、CSSは400行くらいに収まりました。

https://code.visualstudio.com/


ディレクトリ構成は以下です。ファイル名はなんでもいいのですが、参考サイトとあわせておくとやりやすいです。

```ruby:ディレクトリ構成
website/
│
├─ index.html
│    
├─ css
│   └──style.css
│
├─ img
│   └──profile.jpg
│   ├── …　#その他jpgファイル複数
│
├─ php #任意
│   └──send_email.php
│
└── contact.html #任意

```

上記の参考ページにはコンタクト機能がないのですが、割と簡単にできそうだったので追加しました。

### 4. websiteファイルをサーバーにアップロード　所要時間：10分

最初はFileZillaを使用していたのですが、xreaのコントロールパネルから直接操作できることがわかったため、xrea上でファイルをアップロードしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780099/7c72de47-f74b-4b56-6302-45d998bcb227.png)

### 5 . 完成。

最初から100点を目指さず、一旦大枠だけ作成してから徐々に細かな編集をしていきましょう。


# 難しかったこと  

- レンタルサーバー選び
種類が多くてどれを使用するか悩みました。一旦xreaはおすすめできるのですが、他はわかりません。もっと使いやすいものがあるかもしれません。
- CSSの反映
最初CSSが反映されなくて困りました。色々調べてCookieの削除など色々試しましたが、解決せず…。結局わかった原因は、割と簡単なコーディングミスでした。GPTにも聞いていたのですが簡単にいうと検知できないタイプのエラーでした。CSSが反映されない！となっている人は初歩的なミスも確認してみましょう。
- コーディング
HTMLやCSSを実際に書いたのは初めてだったので、色々とわからないところを調べながらの試行錯誤でした。GPTにもたくさん頼りました。ただ、「理解すること」を目指すとほんと終わららないので、とにかく手を動かしサイトを完成させることを優先させた方がいいと思います。やってからわかることは結構あります。