OmniAICreator/Qiita-1.07M huggingface dataset:
【無料アプリ】VPN「TailScale」を使って外出先から自宅のラズパイと通信をする。

## やること
外出先のスマホから4G回線で自宅のラズベリーパイ（ファイルサーバ）と通信する。

設定環境は、
デスクトップPC
ラズベリーパイ
スマホ

それぞれにtailscaleをインストール。
デスクPCとラズベリーパイでtailscaleの1つのアカウントに接続デバイスを追加していく。


参考

https://lifehack-dev.net/post-283/



## ラズパイの初期セットアップ完了からスタートします。

https://qiita.com/SHIJIMI_EN/items/476399577755da1fcd86

https://qiita.com/SHIJIMI_EN/items/9904ae0f17b5d329f192





## スマートフォンにTailScaleをインストール
ストアから検索してインストール。
アカウント作る。グーグルとかGithubのアカウントがあればそれ使えばOK


## PCからtailscaleにアクセス

https://login.tailscale.com/admin/machines

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882753/1e0d4ff3-4ef8-c7ba-c3ff-f9fb2ddd1418.png)


## ラズベリーパイ側の設定
ラズパイターミナルから実行

tailscaleインストールコマンド
```
curl -fsSL https://tailscale.com/install.sh | sh
```

完了メッセージ
```
+ [ false = true ]
+ set +x
Installation complete! Log in to start using Tailscale by running:

sudo tailscale up

```


```
sudo tailscale up
```

完了メッセージ
```
To authenticate, visit:
https://login.tailscale.com/a/xxxxxxxxxxxxx
```

このリンクにPCからアクセスします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882753/bb434345-3433-6b06-53ad-efb477681626.png)

Connectをします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882753/0856db2f-49e7-d411-9875-b5514740381c.png)

Addresses のIPアドレスにスマホから接続できます。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882753/708dc5d0-2d14-8df5-4416-8aaad6ef01e3.png)


## tailscale コマンド
起動
```
sudo systemctl start tailscaled
```
停止
```
sudo systemctl stop tailscaled
```


最後の行をコメントアウト（写真）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882753/ef7d716f-0695-98fb-6e3a-0906920d718a.png)

```
sudo systemctl disable tailscaled
sudo systemctl daemon-reload
```



自動起動有効
```
sudo systemctl enable tailscaled
```

VPNの状態確認
```
sudo systemctl status tailscaled
```



## 自動起動を止めることはできない
いろいろ試したけど自動起動止めれない。
↓ためしたこと

電源投下時に自動起動無効
```
sudo nano /lib/systemd/system/tailscaled.service
```


## tailscaleアンインストール方法
```
sudo systemctl stop tailscaled
sudo apt remove tailscale
sudo apt purge tailscale
sudo apt autoremove
sudo rm -rf /var/lib/tailscale /etc/systemd/system/tailscaled.service.d
```
Composeのチュートリアル

Googleのjetpack-composeチュートリアルを見たので、アウトプットして忘れないようにする。

従来XMLファイルと呼ぶときはsetContentViewを使用するが、コンポーズではsetContentを使用してコンポーズ可能な関数を呼び出す。
BasicsCodelabThemeはコンポーズ可能な関数のスタイルを設定している。

通常の関数に`@Composable`アノテーションをつけることで内部で他の`@Composable`関数を呼び出すことができる。チュートリアルではGreeting関数が`@Compose`として呼び出している。

コンポーズレイアウトをプレビューするには、コンポーズ可能な関数またはデフォルト パラメータを含む関数に`@Preview`アノテーションを付けることで可能になる。



#### 参考

https://developer.android.com/codelabs/jetpack-compose-basics
キャリアが分からない時は具体例を聞こう

SEのフリーランスが当たり前になってきました。
ただ、それでもフリーランスへ転向するのに腰が重たい話も聞きます。
やったことないものに、不安は付きものです。

こういう時は実際にフリーランスで働いている人の話を聞くのをオススメしています。
実際の話を聞いたほうが、具体的なイメージは湧きやすいと思います。

今回は、フリーランスへ転向した具体例をカンタンにご紹介します。

## 会社員からフリーランスへ転向
行動力のある友人Kさんは、元からフリーランスになるためシステムエンジニアを仕事にしたそうです。
そのため、大学時代に専攻していた分野とは、全く違うそうです。

最初はドットインストールやブログの記事など独学でプログラミングを勉強していました。
そこから就職して、会社員として数年間働き、フリーランスとして独立。

最初こそ、プログラミングのハードルは高かったそうですが、今ではフロントエンドもバックエンドもできるSEへ。
フリーランスになってからできる幅を広げるように意識してきたそうです。

ただ、最初はフリーランスとして仕事をすることに不安があったそうです。
- 確定申告は？
- 仕事の責任は？

彼もフリーランスの先輩に相談しながら、少しずつできるようにしてきたと話していました。
**案件を切り替えるごとに新しいスキルを身につけられるのが、メリットだそうです。**
実際、最初はPHPだけだったところから、AWSやpython、Vue.jsなど幅広くスキルを習得してました。

### さいごに
今回は簡単な一例ですが、IT系はconnpassやTECH PLAY（テックプレイ）でフリーランスの人と話せるイベントを探せます。

こちらの記事でも、イベントに参加することのメリットを書いています。

https://qiita.com/ono-ayumu/items/a1128c3a5e370c96c6dc

実際の話を会って話を聞くの大事ですね。

https://connpass.com/

https://techplay.jp/
就活のためにwebアプリ（Spring boot＋FireBase Storage+React）を作成している話

## はじめに
始めまして，2026新卒のnishikiです．
今回初投稿です．

この度，就活に使える成果物を作成したいと思い，バックエンド～フロントエンドまでを含めたwebアプリの開発に挑戦しました（というか今しています）．
自身のためのメモとして，また未来の就活生の糧になればいいと思い，筆を執った次第です．

余りこの記事に時間を使うつもりはないので，ところどころ適当になるかもしれませんが，初学者のあがき方として参考にしていただければと思います．

## 自己紹介・今まで使ったことのある言語
改めまして，就活真っ最中のnishikiと申します．
趣味としては，オーケストラでヴァイオリンを弾いたりしています．
現在は某理系大学院にM1として所属しており，普段は余りコードをいじらない研究をしています．
一方，プログラミング自体は広く浅く経験しており，一応以下の言語を触ったことがあります．
- Python
研究で使ったり，趣味として何かやりたいと思ったらとりあえず使っています．
- Flutter/Dart
勉強し始めて半年強になります．実務経験はないですが，ちゃんとGUIのあるアプリを作ってみたいと思い勉強し始めました．
- HTML・CSS・JavaScript
一般的な入門サイトは一通りさらった程度の経験です．発展的なものはあまり作ったことが無いです．
- GAS
実質JavaScriptですが，普段の事務的な業務に使っています．めっちゃ便利！みんなも使おう！
- React
某企業でハッカソン形式の夏インターンに参加し，開発を経験しました．実装力の高いメンバーに恵まれたので，短期間で色々なことを学ばせてもらいました．

## 作りたいアプリの概要
### 技術スタック
第一に就活の成果物として利用できる点が重要なのですが，某L社の就活アドバイザーによると以下の点が重要なようです．

-  **バックエンド＆フロントエンドの実装**
これを行うことでアプリケーションの仕組みを理解したことが示せます．
-  **フレームワークの利用**
企業の開発環境に近い環境で開発していることを示せることと，単純に開発がしやすくなる点で利用した方がよいようです．

これらの条件を満たす成果物として，**webアプリ**の開発が適しているとアドバイスをもらいました．

正直なところあまり知識のない分野で迷いましたが，餅は餅屋ということで成果物の形態としてはwebアプリを選びました．
具体的には，フロントエンドとして少し経験のあったReact，バックエンドとしてSpring boot，データベースとしてFireBase Storageを用いることにしました．
バックエンドとしてDjangoでなくSpring bootを選んだ理由ですが，完成形としてJavaアプリを利用した処理を実行したかったので(pythonから動かすことも不可能ではないですが)それに合わせています．

### アプリ概要
アドバイザーによると，面接で成果物について説明するためここの動機付けもしっかりとやるべきだそうです．自分の言葉で語りやすいということで，今回は趣味のオーケストラで経験した出来事をもとに決めました．
具体的には，楽譜をアップロードすると移調をしてくれるようなアプリを完成形として目指します．元となったエピソードはここで説明するようなものでもないと思うので，折りたたんでおきます．

<details><summary>元となったエピソード</summary>
小編成の室内楽などでは，他の楽器用の楽譜を自分の楽器で演奏することもあります．ここで問題になるのが，楽譜の調の問題です．
ト音記号とヘ音記号の違いは音楽の授業でも扱うかもしれませんが，場合によっては同じト音記号の楽譜を違う音として扱う場合もあり，これが異なる楽譜を演奏することは非常に難しいです．
そこで，楽譜の調を変えて普段の楽譜と同じ調にできるようなアプリを作りたいと思った次第です．
</details>

ざっくりとした処理の流れは，次のものを想定しています．（本来はシーケンス図が必要ですが，本格的に開発に入ってからにします．）
- フロントエンドで楽譜画像を受け取る
- クラウドデータベースへのアップロード，バックエンドへのAPIコールを行う
- バックエンド側で画像を再取得，Audiverseというアプリを用いてMIDI（楽譜の情報を電子データとして扱う際の形式）に変換
- MIDIを操作し移調
- 再びpngやpdfに変換し，データベースにアップロード
- フロントエンドにレスポンスを送る
- フロントエンド側で結果表示＆必要に応じてダウンロード

ただ，難しそうなら途中で難易度を下げる予定です．


## 勉強に参考にしたサイト
この段階では，Spring bootによるバックエンドの実装，Firebaseによるデータベースの利用の経験がありませんでした．
そこで，以下のサイトを参考（写経）に勉強しました．
**ToDoアプリ**
spring bootのチュートリアルとして参考にさせていただきました．

https://qiita.com/toki_dev/items/f9fcdf7d65f3a8ab0f23

https://qiita.com/toki_dev/items/e207157c679018579e21

**画像投稿機能**
Firebaseのチュートリアルとして，以下のサイトを参考にさせていただきました．

https://qiita.com/Naoya_pro/items/833d91f51770892abeb1

## 勉強した結果
Spring bootは，基本的なController，Mapperの使い方を学ぶことができましたが，まだまだ他の要素も多いようですので，追加で学びながら開発することになりそうです．
また，SQLによるデータベース処理についてもここで触れられたのはよかったと思います．
MVCモデルやRestAPIという単語についても触れられたのは大きかったです．

FireBaseは，簡単に使うことができて非常に有用なサービスであると感じました．
ToDoアプリで既にデータベース操作に触れていたことも，理解に貢献していたかもしれません．

## 今後の予定
次は，ReactとSpring bootの連携について学んでいく予定です．

次回⇒モチベーションが続いて就活の方針が変わらなければ11月中
突然、EC2サーバが落ちた話

## 体験談
ある日、AWSから`AWS_EC2_PERSISTENT_INSTANCE_RETIREMENT_SCHEDULED`の通知が届きました。いわゆる「リタイア通知」です。

内容を確認すると何やら物騒なことが書かれています。
`Due to this degradation your instance could already be unreachable.`
つまり既にインスタンスにアクセスできなくなっている可能性があるということを意味します。

私の（誤った）認識ではこの文章はあくまで「保険」的なニュアンスで書かれているものであり、通知文に記載されている対応期限前に突然サーバーが落ちる可能性は流石に低いだろうと、たかを括っていました。

とはいえ念の為、対象インスタンスを確認しにいくとインスタンスの状態は「✅実行中」ですが、メトリクスの部分で「特定時間帯からデータがない状態」が発生しているではありませんか。

ファッ!? (゜Д゜;)
まさにこんな顔になっていたと思います。
この時点でなんだか悪い予感がしてきます。

次にターゲットグループを見にいったら、案の定「✖️異常」状態になっているインスタンスが1つあり、確信に変わりました。サーバが、、、落ちて、、、いました。
（幸い、冗長化はしていたのでサービス自体に大きな影響はありませんでした。）

「もうこうなったら今、リタイア通知の件の対応をしてしまおう」ということで、ターゲットグループから対象インスタンスを外し、「インスタンスの停止」と「インスタンスの起動」を行い、無事に復旧しました。
（※補足：インスタンスの再起動ではダメらしい）

時間帯的にもそんなにアクセスが多くはなかったので、なんとか無事でしたがヒヤリとした体験談でした。

## まとめ
この時ほど「冗長化しておいて良かったぁぁ」と実感したことはありませんでした。
一方で死活監視部分の甘さもかなり痛感した出来事となりました。

コストが多少かかるとしても今回のような事象が発生し得るので、冗長化はしておくことをお勧めします。
ここまでお読み頂き、ありがとうございました。
少しでも学びになれば幸いです。
An error occurred (UnrecognizedClientException) when calling the GetAuthorizationToken operation:の対処法

<h2>症状</h2>
ECSにPUSHしようとしたときに下記のメッセージが表示されました。

```terminal:error
 aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin hoge.dkr.ecr.ap-northeast-1.amazonaws.com
northeast-1.amazonaws.com

An error occurred (UnrecognizedClientException) when calling the GetAuthorizationToken operation: The security token included in the request is invalid.
Error: Cannot perform an interactive login from a non TTY device
```

```terminal:翻訳
GetAuthorizationToken 操作の呼び出し時にエラー (UnrecognizedClientException) が発生しました: 要求に含まれるセキュリティ トークンが無効です。
エラー: TTY 以外のデバイスから対話型ログインを実行できません
```

認証エラーが出ているみたい

<h2>解決策</h2>
aws configreでAWSCLIにログインする為の設定を行うことで、エラーが解消されました

```
 aws configure
AWS Access Key ID []: アクセスキーを書くところ
AWS Secret Access Key []: シークレットアクセスキーを書くところ   
Default region name [None]: リージョンを書くところ
Default output format [None]: 出力結果の形式を書くところ
```

<h2>参考</h2>

https://qiita.com/igz0/items/1227618b5836fa81ca91

https://qiita.com/raimu_hosoda/items/24b587fe44ced5262722

https://zenn.dev/mo_ri_regen/articles/aws-cli-setting

https://maku.blog/p/j5iu7it/
【Windows】VScodeのターミナルでペーストする方法

WindowsのVSCode上ターミナルで、AWSCLI認証時にアクセスキーなどをペーストする際にうまくいかず、10分くらいハマったので、ここに記す

Ctrl+Shift+V

これでコピーしてあるものを、ペーストできる

<h2>参考</h2>

https://www.silicloud.com/ja/blog/linux-%e3%81%ae%e3%82%bf%e3%83%bc%e3%83%9f%e3%83%8a%e3%83%ab%e3%81%a7%e3%82%b3%e3%83%94%e3%83%bc%ef%bc%86%e3%83%9a%e3%83%bc%e3%82%b9%e3%83%88%e3%81%99%e3%82%8b%e6%96%b9%e6%b3%95%e3%82%92%e6%95%99/
【個人メモ】Ruby on Rails チュートリアル 第8章

Ruby on Railsチュートリアルで学んだ内容を個人的なメモとして簡単にまとめたものです

# 個人メモ
- Sessionを設定することでコンピュータ間（ユーザーのパソコンのWebブラウザとRailsサーバーなど）を半永続的に接続することが可能
- cookies
ユーザーのブラウザに保存される小さなテキストデータのこと
Cookiesを保存場所とすることでセッション機能を実現する
- form_with(url: login_path, scope: :session)
セッションではSessionモデルがなく、そのためsessionインスタンス変数に相当するものがない
したがって、form_withヘルパーにはscopeとurlを指定する必要がある
- Rubyではnilとfalse以外のすべてのオブジェクトは、真偽値ではtrueになる
- flash.nowのメッセージはその後リクエストが発生したときに消滅する
- 全コントローラの親クラスである「Applicationコントローラ」にセッションヘルパーをincludeすることでどのコントローラからでもメソッドを呼び出せる（この章で実装するログイン機構は様々な場面で用いるため）
- sessionメソッド
ユーザーのブラウザ内の一時cookiesに暗号化済みのユーザーIDが自動で作成される
- メモ化（memorization）
メソッド呼び出しの結果を変数に保存し、次回以降の呼び出しで結果を再利用する手法
- user_path
引数にidを指定すると自動でパスに変換してくれるヘルパーメソッド
なお、引数がオブジェクトであることを自動で認識するため省略できる
- ブラウザで「検証」より「デバイスのツールバーを切り替え」機能を利用すると、様々なモバイルデバイスでアプリがどのように表示されるか確認できる
- fixture
テスト用のデータ
ユーザーがログインできることを確認するテストにて用いる
- digestメソッド
渡された文字列のハッシュ値を返すメソッド
テストではハッシュを算出するためのコストを最小にし、本番では通常の高いコストで計算する
- reset_sessionメソッド
すべてのセッション変数をリセットできる
- status: :see_other（303 See Otherステータス）
DERETEリクエスト時のステータス
Raisにおけるキャメルケースとスネークケースの使い分け

細々とrailsを使ってwebアプリケーションを作る練習をしています。

今回はpostテーブルにマイグレーションファイルが設定できなかった件についてまとめておきます。
結論から言うと、
 「AddUserIdToPosts」とすべきところを、
 「AddUserIdtoPosts」と大文字と小文字を間違えていたからでした。

 今回のエラー（というか凡ミス）を解決する中で、
 railsには「なんで小文字とアンダースコアで単語をつなぐ時と、大文字と小文字で単語をつなぐ時があるんだろう？」と気になるようになりました。

 ChatGPTに相談しまくった結果を簡単にまとめると、
 
・クラス名のとき：最初の文字が大文字で、各単語の最初も大文字で記述する。（キャメルケース）
例：UserProfileやAddUserIdToPosts

・メソッド名、変数名、カラム名: すべて小文字で、単語の間をアンダースコアで記述する。（スネークケース）
例：メソッド名（def get_user_nameやdef calculate_total_price）、変数名（user_idやpost_title）、データベースのカラム名（created_atやupdated_at）
 ということでした。
 
 （ちなみにアンダースコアとはアンダーバーは同じ意味ということもこの度初めて知りました。今までアンダーバーと言ってましたが、これからはアンダースコアと呼ぶようにします）


 キャメルケースとスネークケースで使う場面が違うということを頭に入れておけば、今後入力ミスをしてもすぐに気づけるようになりそうです！
Typstで式を引用したときだけ式番号をつける

引用した式にだけ式番号をつけたい時がある．LaTeXではautonumパッケージなどを使えば実現できる．Typstでも同じようなことができ，その方法は[この記事](https://qiita.com/tomoyatajika/items/bf52a066874f7370c77a
)で紹介した．
しかし，記事で紹介した方法ではいちいち関数で囲む必要があった．

以下のようにすれば，そのようなことをせずとも自動で式を引用したときだけ式番号をつけることができる．

```rust
#set math.equation(numbering: "(1)")

#show math.equation.where(block: true): it => {
   let eqbox(eq) = context{
        let par-h = par.spacing
        box(eq,outset:par-h/2, width:100%)}
  if it.has("label")  {
      let tlabel = it.at("label")
     context{
        let  eql = counter("auto-numbering-eq" + str(tlabel))
        if eql.final().at(0) == 1{
          eqbox(it) 
          }
        else {
          counter(math.equation).update(n => n - 1)
          eqbox($display(it.body)$)
        }
      }
    
  }
  else {counter(math.equation).update(n => n - 1)
        eqbox($display(it.body)$)}
}

#let eq_refstyle(it) = {
  return  {
  let lbl = it.target
  let eq = math.equation
  let el = it.element
  let eql = counter("auto-numbering-eq"+str(lbl))
  eql.update(1)
  if el != none and el.func() == eq {
      link(lbl)[
      #numbering(
        el.numbering,
        ..counter(eq).at(el.location())
      ) ]
  } 
    else {it}
  }
}

#show ref: it => eq_refstyle(it)
```

ただし，式番号をつけるときとつけないときで若干式周りのスペースが変化してしまうので微調整している．これは設定次第では壊れるかもしれない．
<2025/3/16追記> box環境で囲むことにより前後の空白のスペースをラベルありなしで統一できるようにした．
linux コマンド一覧

ただの備忘録
少しずつ更新します。

## いろいろ
| コマンド |  |
|:-------:|:-----|
| cd | ディレクトリの移動。引数を指定しない場合は最初のディレクトリに戻る。 |
| pwd | 現在のディレクトリを表示する。 |
| mkdir | ディレクトリを作成する。 |
| ls | ファイル・ディレクトリを一覧表示する。 |
| find | ファイル・ディレクトリを検索する。 |
| which | コマンドを検索する。（`.exe`など） |

## 削除
| コマンド |  |
|:-------:|:-----|
| rm | ファイルを削除する。 |
| rmdir | 空のディレクトリを削除する。|
| rm -r ディレクト名 | ディレクトリと、その中にあるファイルを削除する。|
GetDetailsOf：最新のファイルプロパティとインデックスの関係性を確認する

# 目的
この記事では、PowerShellの GetDetailsOf メソッドを使って、特定のファイルに関連する詳細情報の最新インデックスを取得する方法についてお話しします。<br> Windowsファイルシステムは多くのプロパティを持っていますが、そのインデックスや内容に関する情報は公式ドキュメントやウェブ上で見つかるものが古かったり、正確でなかったりすることがよくあります。<br> そこで、実際に自分の手で各インデックスから取得できる値を確認するのが良いでしょう。

# 背景
GetDetailsOf は、特定のファイルやフォルダについての詳細情報を取得するために便利なメソッドです。<br> しかし、利用する際のプロパティのインデックスやその内容に関する情報が不足していることが多く、自分自身で確認する必要があります。<br> 特に特定のファイルタイプやフォルダにおけるメタデータを扱う際には、自分で調査することが非常に役立ちます。

# コード
以下に示すのは、指定したファイルのプロパティを調査するためのPowerShellスクリプトです。<br> このスクリプトでは、ファイルパスを入力すると、最大300のインデックスに対して詳細情報を取得し、各インデックスの値をコンソールに表示します。

~~~powershell:sample.ps1
# プロパティを調べたいファイルを指定
$path = "C:\path\to\your\file.txt"  # ファイルのパスを指定してください

$shell = New-Object -COMObject Shell.Application

# フォルダとファイル名を変数に設定
$folder = Split-Path $path
$file = Split-Path $path -Leaf

$Getfolder = $shell.Namespace($folder)
$Getfile = $Getfolder.ParseName($file)
$count = 0

# 最大300のインデックスに対して詳細情報を取得
while ($count -lt 300) {
    $result = $Getfolder.GetDetailsOf($Getfile, $count)
    Write-Host "$count: $result"
    $count++
}
~~~

# スクリプトの説明

* ファイルパスの指定:
$path 変数に調査対象のファイルパスを指定します。必要に応じてこのパスを変更してください。
<brk>

* Shell.Applicationオブジェクトの作成:
New-Object -COMObject Shell.Application を使用して、WindowsのシェルにアクセスするためのCOMオブジェクトを作成します。
<brk>

* フォルダとファイル名の取得:
 Split-Path を使用して、指定したパスからフォルダパスとファイル名を抽出します。
<brk>

* フォルダとファイルの詳細情報を取得:
Namespace メソッドで指定したフォルダの情報を取得し、ParseName メソッドで特定のファイルに対するオブジェクトを取得します。
<brk>

* インデックスのループ処理:
while ループを使用して、0から299までのインデックスを走査します。各インデックスで GetDetailsOf を呼び出し、その結果をコンソールに表示します。

# 結論
このスクリプトを使うことで、特定のファイルに関連する詳細情報のインデックスを確認し、どんなプロパティが利用できるかを把握することができます。<br> Windowsファイルシステムのメタデータを扱う際に、ぜひ試してみてください。<br> あなた自身の手で情報を探り出すことで、新しい発見があるかもしれません！
フリーランスエンジニアは少ないのか？その実態と理由を探る

ここ数年、フリーランスエンジニアの働き方が注目されています。リモートワークの普及やITスキルの需要増加とともに、フリーランスとしての働き方が現実的で魅力的な選択肢となり、多くのエンジニアが独立を視野に入れるようになりました。しかし、実際にはフリーランスエンジニアの数はそれほど多くはなく、フリーランスへの移行に慎重なエンジニアも少なくありません。この記事では、フリーランスエンジニアが少ない理由と、その実態について考察します。

1. フリーランスエンジニアの現状
フリーランスエンジニアとは、企業に所属せずに個人でプロジェクトや業務を請け負うエンジニアのことを指します。日本ではITエンジニアの数は増加傾向にあるものの、そのうちフリーランスで活動しているエンジニアは少数派とされています。フリーランスエンジニアの数が少ない理由には、経済面や労働環境、社会的な認知度といった多様な要因が影響しています。

2. フリーランスエンジニアが少ない理由
フリーランスエンジニアが少ない理由を、大きく以下の4つに分けて解説します。

① 安定した収入の確保が難しい
フリーランスエンジニアは、プロジェクトごとに報酬が発生するため、定期的な収入が確保しにくい点が挙げられます。特に、経験が浅いエンジニアや知名度が低いエンジニアの場合、安定して仕事を受注することが難しく、収入が不安定になることが多いです。エージェントやクラウドソーシングサイトを通じて仕事を得ることもできますが、案件の数が限られていたり、手数料がかかることもあります。

② 福利厚生や社会保障の不安
フリーランスエンジニアは、会社員のような福利厚生や社会保険がないため、医療保険や年金の手配をすべて自分で行う必要があります。また、病気や怪我で働けない期間の収入が保証されないため、予期せぬ出費や生活費の不安を抱えがちです。特に家族を持つエンジニアにとっては、福利厚生の有無がフリーランスへの転向を躊躇する大きな要因となっています。

③ 自己管理やマーケティング能力が求められる
フリーランスエンジニアとして活躍するためには、エンジニアとしてのスキルだけでなく、自己管理能力やマーケティング力も必要です。案件の受注からスケジュール管理、クライアントとの交渉、報酬の請求など、ビジネス全般の知識が求められます。これに加えて、SNSやブログを活用して自己のスキルや実績をアピールするマーケティング力も重要です。これらを苦手とするエンジニアにとって、フリーランスで活動することは大きなハードルとなっています。

④ キャリアアップの難しさ
フリーランスエンジニアは組織に所属しないため、キャリアパスが見えにくいという課題もあります。企業に所属していれば、スキルの習得やプロジェクトの経験を通じてキャリアアップが期待できることが多いですが、フリーランスでは自ら積極的に学び、キャリアを切り拓く必要があります。案件の内容もプロジェクトごとに異なるため、同じスキルを深める機会が限られ、専門性を磨くことが難しい場合もあります。

3. それでもフリーランスエンジニアが選ばれる理由
フリーランスエンジニアは少ないものの、実際にこの道を選ぶエンジニアには明確な理由があります。最大のメリットは、自由な働き方が可能である点です。フリーランスでは、案件や働く時間、働く場所を自分で決めることができるため、ワークライフバランスの向上や、家族との時間を大切にすることが可能です。また、報酬の交渉次第では高収入も期待でき、特にニッチなスキルを持つエンジニアは、企業に属するよりも高い報酬を得ることが可能です。

4. フリーランスエンジニアの将来性
デジタル化やリモートワークが広がる現在、フリーランスエンジニアの働き方は注目されています。IT業界では、プロジェクトベースでの契約が増えており、企業側もフリーランスエンジニアを採用するケースが増えつつあります。また、エージェントやクラウドソーシングプラットフォームも充実し、以前よりも案件の種類や報酬面での条件が向上しているため、フリーランスに転向するハードルは下がりつつあります。

5. フリーランスエンジニアを目指すための準備
[フリーランスエンジニアとして成功](https://www.freelanceitengineeragent.com/)するためには、以下のような準備が重要です。

スキルの磨き直し: 特定の分野での高い専門性は大きな武器になります。特に需要が高いプログラミング言語や、最新の技術を習得しておくと案件獲得がスムーズです。
実績の公開: ポートフォリオサイトやSNSで自身の実績を公開し、クライアントにアピールすることで、信頼性が高まります。
自己管理スキルの向上: スケジュールやタスク管理を徹底し、納期を守ることでクライアントからの信頼を得られます。
まとめ
フリーランスエンジニアの数はまだ少数派ですが、その需要は確実に増加しています。安定性や福利厚生の問題が課題となっている一方で、自由な働き方や高収入の可能性も魅力的です。IT業界の需要に応じてフリーランスエンジニアの働き方が広がっていく中で、慎重に準備を行い、自分に合った働き方を見つけることが成功への道となるでしょう。
IBM iで正規表現（２）【バックスラッシュを使用したい場合】

## はじめに

前回は[IBM iで正規表現（１）【FF RPGでの使い方】](https://qiita.com/tamaday/items/015b7ea316977721131e)についてご紹介しました。

IBM iで正規表現を使用する際には、1つ問題があります。
具体的には、IBM iでは「\（バックスラッシュ）」が「￥（円マーク）」として認識されてしまうことです。

今回は、IBM iで正規表現を使う際に、バックスラッシュを扱う方法をご紹介します。
本記事では、CCSIDに5035を使用しています。

## 検証環境
* PC環境：Windows10 日本語
* エミュレータ：P-COMM 15.0 ホストコードページ 939
* IBM i:V7R5 CCSID 5035

## なぜバックスラッシュが使用できないのか？

こちらの記事でご調査いただいている通り、エミュレータソフトの違いによって文字の見え方が異なることがあります。

[IBMiのWeb開発では円マークに気をつけよう](https://qiita.com/ushiday/items/409fb24028aedd44ef16)

## IBM iで正規表現を使う際に、バックスラッシュを扱う方法

CCSID 5035では、バックスラッシュを16進数で「E0」と表されます。
そのため、バックスラッシュを「X'E0'」として、16進数で直接表現します。

```rpgle
REGEX = '^' + X'E0' + 'd{7}$';

EXEC SQL                                                    
     Set :COUNT = REGEXP_COUNT(TRIM(:INPUT), :REGEX);
```

ご参考になれば幸いです。最後までお読み頂きありがとうございます。
【github】WindowsPC上でGithubとVSCodeを連携してみた

## 【初心者向け】VSCodeとGithubの連携 for Windows 
私は、インフラエンジニアとして仕事をしているのですが、最近AWSというクラウドサービスに興味があり、勉強に励んでいるクラウド未経験の者です。
　
　その際に、IaCというAWS上のインフラリソースをコード化して作成や管理ができる機能について知り、自身のポートフォリオの準備のためにも、VSCodeでIacを作成したものをGithub上に公開しています。

　VSCodeとGithub連携は、初学者にとっても簡単なので、よければ参考にしてください。

## 作業手順
１．VSCodeのインストール
　インストール方法については、とても分かりやすく解説している、こちらの記事を見て作業を行ってください。

https://breezegroup.co.jp/201904/visualstudiocode/


２．Gitのインストール
　GitはGithubのコードのバージョン管理をしているシステムツールで、Windowsの場合は、下記のサイトから、自分でインストールする必要があります。

https://git-scm.com/ 

・基本的に赤で囲んだ部分をクリック
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3898218/b83e9302-bcf5-13ea-2cc0-2de08faa57a8.png)

・自身のPCが32bit or 64bitを確認して選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3898218/ede74374-daff-92fa-3848-ade18bd88479.png)

・ダウンロードした上記の資材を管理者として実行し、インストールを行う。

３．Githubアカウント登録
　下記のサイトにアクセスして、アカウント登録を行う。

https://github.co.jp/

４．VSCodeとGithubの連携

➀　Githubでリモートリポジトリ作成
・Githubへログインして、ユーザページへ移動（https://github.co.jp/）

・[Repository name]に作成したいリポジトリ名を入力して、[Create a new repository]をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3898218/9cb8befb-da93-669d-956d-2500fee3908b.png)

・こんな画面が表示されたらOK！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3898218/51a8b4de-93cd-7902-3694-3a670697cbe7.png)


➁VSCodeでリポジトリクローン
・画面左バーのアイコンをクリックし、[リポジトリの複製]を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3898218/43b5c194-feb8-ee66-5212-4f19156be4e0.png)

・上の検索バーに[Githubから検索]が表示されるので、クリックすると➀で作成したリポジトリ名のURLが表示されるので、それを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3898218/b6a120d4-f30d-23f1-f1c7-9a50fddc6655.png)

・本来なら下記のような表示がポップアップしていますので、[許可]　→　[continue]を選択し、自身のGtihubアカウント情報の入力後にサインインする。
（私は接続済みのため、別サイトからの引用）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3898218/b791306e-d89d-303b-3626-c72ddb7d9b16.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3898218/f53f9377-0b36-13df-e5d8-b5d5ccb2a0f5.png)

・リポジトリクローンのフォルダ先の選択
（いわゆるローカルリポジトリ）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3898218/d8d90bc1-2e8b-8eb5-ec59-8a08533f9a14.png)

・[フォルダーを開く]を選択し、上記で作成したローカルリポジトリを開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3898218/8aaeb12c-2cc7-0719-8788-65ad205f194b.png)

・あとは、ファイルを作成して、コーディング開始！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3898218/78f78a0c-0a7e-dd56-90a3-33ddb0d7eb0b.png)

## まとめ
長い作業についてきてくれて、皆さんお疲れさまでした。
細かい部分や抜けがある部分もあるかと思いますが、それらの疑問がある場合は、遠慮なく、コメントを頂けると嬉しいです。

ここの作業さえ完了してしまえば、あとはガリガリとコードを書きまくるのみですね（笑）

今後、時間があれば作成したコードをGithubへpushやpullの解説もやってみようと思います。
【ROS2】USBカメラ映像のストリーミング

# 対象となる読者

:::note info
- ROS2を使ってUSBカメラの映像を取得したい人
- USBカメラのpermissionを設定したい人
:::

# 開発環境
再現を容易にするためハード，ソフトの環境を事細かに記載しておく

## ハードウェア

https://www.switch-science.com/products/9250?srsltid=AfmBOoqO0R74mDFwv5EoP7Whfliq4iKLp__un9T0Is2Yv-fTS6uxtnfR

https://www.logicool.co.jp/ja-jp/products/webcams/hd-webcam-c270n.html

## ソフトウェア

https://www.ubuntulinux.jp/News/ubuntu2404

https://docs.ros.org/en/humble/Releases/Release-Jazzy-Jalisco.html

https://gnome-terminator.org/

- python3.12

# 手順

:::note warn
簡単に映像取得を試すために[ROS2とPythonで作って学ぶAIロボット入門](https://www.amazon.co.jp/ROS2%E3%81%A8Python%E3%81%A7%E4%BD%9C%E3%81%A3%E3%81%A6%E5%AD%A6%E3%81%B6AI%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E5%85%A5%E9%96%80-KS%E7%90%86%E5%B7%A5%E5%AD%A6%E5%B0%82%E9%96%80%E6%9B%B8-%E5%87%BA%E6%9D%91-%E5%85%AC%E6%88%90/dp/4065289564)の「第5章 ビジョン」に記載の手順を踏襲して実施
:::

https://github.com/AI-Robot-Book/chapter5

## 必要ライブラリのinstall
```bash
pip3 install opencv-contrib-python==4.10.0.84
sudo apt install ros-jazzy-vision-opencv ros-jazzy-usb-cam
```

https://pypi.org/project/opencv-contrib-python/

- OpenCVと拡張モジュール群をまとめてinstallできるライブラリ

```ros-jazzy-vision-opencv```
- ros2とopencvとを繋ぐインターフェース
- ros2のtopicをopencvが受け取るために必要

```ros-jazzy-usb-cam```
- usbカメラ用のnodeを生成するパッケージ

## 実行

:::note warn
実行しているコードはsample codeそのままなのでここでは省略
:::

やるべき手順は以下の通り

1. ```usb_cam_node```の立ち上げ
    1. ```bash
        ros2 run usb_cam usb_cam_node_exe
        ```
1. OpenCVを使ったコードのnode立ち上げ
    1. 今回は```front_camera_node```という名前にした
    1. ```bash
        ros2 run front_camera front_camera_node
        ```
1. ```rqt```によるimage topicの表示
    1. ```bash
        rqt
        ```

:::note info
それぞれを動かすためのterminalが必要なので事前に用意しておく
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2043769/340c6c21-81a3-bc94-3fdf-0beb157b1675.png)

```rqt_graph```も使うとnode毎の繋がりが視覚化されるので，上手く動かない場合は使ってみると欲しいnodeが繋がっていないとかを見ることができる

# Tips: usbカメラのpermission errorの解消
root user以外がusbカメラにアクセスすると以下のようなErrorではじかれてしまう

```bash
[ERROR] [1730529629.400962429] [usb_cam]: Device specified is not available or is not a vaild V4L2 device: /dev/video0 
```

これはpermissionが制限されているために起こるErrorであるため，root user以外からもアクセスできるようにしてあげればいい

### 一時的にpermissionを通す場合

```bash
sudo chmod 777 /dev/video0
```

全てのuserに全権限を渡すため，書き換えやアクセスなどを自由にできる

:::note alert
以下の2つの問題から基本的にはbad case
- 複数のuserが好きにシステムの改変ができてしまう
- あくまで一時的な対応であるため，usbカメラを外す，再起動する，などでpermissionは元に戻る
:::

### 恒久的にpermissionを通す場合

```bash
sudo usermod -aG video $USER
```

現在使っているuserがvideoのアクセスに関するgroupに追加する
こうすることで誰がvideoにアクセスできるかを管理でき，かつ他のデバイスが追加されてもアクセスができる

# 感想
改めて整理すると結構シンプルな構成でROS2を使ったストリーミングができた
ただしterminalを複数立ち上げるのは大変なので，ロボット起動の際には一度にすべてのnodeを立ち上げられるように設定ファイルを書いておきたい
最新のステレオ計算をモジュール化してみた

ここ数年で、ステレオ計算の性能が高くなってきている。
しかし、初心者が最初に使うモジュールはきっと、OpenCVのSGBMの実装だろう。

SGBM の実装は古く、近年の進展を反映していない。

## やったこと

そこで、
1. 最近のステレオ計測でGitHubで公開されている実装の１つをgit clone した。
2. そのまま動作を確認した。
3. 自分のほしいインタフェースを追加した
3. モジュールとしてpip install できるように移植した。
3. それを、GitHubに公開した。

以下は、その詳細についてのメモです。

## 論文調査：久しぶりにさわるステレオ計測分野はどう変わったのか
- サーベイ論文を見つけて読む。
- そのなかで、GitHubに公開しているもので、商業利用してもいいライセンスのものをみつける。
- そのときの調査結果
　[ステレオ計算ライブラリを調査中 2024年版](https://qiita.com/nonbiri15/items/025d4472efaf1704a8d5)

## 実装の１つを試してみる。git clone
1. Docker環境で動作を確認する。
1. 動作環境にJetson　AGX Orinを利用した。
    1. GPUがないノートPCより、GPUのあるJetson（CUDAが使える)
1. Jetson 用のPyTorchのDocker Imageを用意する。
[NVIDIA L4T PyTorch](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/l4t-pytorch)
それを元にして、インストール手順をDockerfileに記述していく。
それをdocker build でdocker環境構築する。
雛形となる例題をまねていけば、Dockerfileを書き直していくのは難しくない。


## ライブラリ化するためのリポジトリを作る。
- 参照した元のコードのライセンスを確認すること
- README.mdに元のリポジトリが何なのかを記載しておく。


## 自分のほしい使い方に書き換えてみる。
もとになった実装は、ファイル入力、ファイル出力だろう。
でも、ステレオ計測は、左カメラ画像、右カメラ画像に対して実行したいだろう。
OpenCVを経由でcv2.VideoCapture()からread()している場合には、
カメラ画像はnp.ndarray型だろう。
そうすると、ファイル名を引数としている関数では使い勝手が悪い。
np.ndarray型を引数とする関数を抽出する。

## モジュールファイルに抜き出す。
ステレオ処理を実行する上で必須の部分と、そうでない部分を切り分ける。
画像データをnp.ndarray型で扱うことを決めたときに、
```
def predict(left: np.ndarray, right: np.ndarray) -> np.ndarray:
```
このようなインタフェースになる。

ファイル名を引数とするインタフェースは、モジュールファイルに含めないという選択ができる。

#### 関数として実装するのか、クラスとメソッドとして実装するのか
- ステレオ計測のときに、引数に画像データだけをpredict()するタイミング与えたい。
- それ以外の設定パラメータは、predict()するタイミングには意識しなくてよくしたい。
- 学習済みのモデルを事前に読み込んでおきたい。
こういう理由のため、ステレオ計測処理の実装は、クラスとして実装してpredict()はメソッドとして実装するのがよいと考える。

## 視差表示ライブラリとの連動を試してみる
[視差を可視化するモジュールを作ってみた](https://qiita.com/nonbiri15/items/d30733be3249d8512ef500
)で紹介したモジュールを使って表示を行うようにした。

[https://github.com/katsunori-waragai/disparity-view](https://github.com/katsunori-waragai/disparity-view)


## pyproject.tomlを書く
python3 -m pip install .
でモジュールをインストールできるように、pyproject.tomlを書く。
その状況で、モジュールを利用したスクリプトの動作を検証する。

## pytest用のテストスクリプトを書く。
pytest test*.py
でテストできるように、テストスクリプトを書く。
モジュールの実装が壊れたら、きちんと見つけられるようにテストを作っておく。

## 少しだけ異なる環境でインストールしてみる
OSのバージョンが違うとか、pythonのバージョンが異なるとか、少し違う環境で動作させてみる。
そうすると、環境の違いによってpipで入るライブラリのバージョンが異なってくることで、想定した動作をしなくなることがある。
動作しない理由を解析して、対策を実施する。

## USBカメラ入力でのステレオ計測の結果を表示を動作させる。
- StereoLabs のZED2iカメラでは、左画像と右画像を連結した画像をUSBカメラとして出力できる。
- そこで、そのUSBカメラ画像をCv2.VideoCapture(0) を用いて、取り込みステレオ計測するサンプルプログラムを作った。
- このスクリプトではZED SDKをインストールしていないUbuntuマシンでも動作した。


## そのAPI設計は妥当なのか
せっかくだから、StereoSGBMを類似のメソッドで利用できるように、ライブラリ化をしてみた。
やったことは、インタフェースを変更したwrapperを書いただけで、アルゴリズムの根幹の部分はいっさい手を加えていない。
[libstereosgbm](https://github.com/katsunori-waragai/libstereosgbm)

異なるアルゴリズムであっても、目的な同じアルゴリズムであれば、同様なインタフェースで利用できるゔぇきだと考える。
だから、２つの実装をし終えてみて、同様なインタフェースにすることができた。
だから、ステレオ視差計算をえるインターフェースとしては、おかしくない実装になったのではないかと期待している。

モジュール化してみたリポジトリ
[libIGEVStereo](https://github.com/katsunori-waragai/libIGEVStereo)
バリデーションの真偽判定のメソッドを使用する条件分岐の注意点

## 初めに

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

## 発端

モデルで以下のように定義
```
with_options if: :exampled? do
    validates :aa, aa_format: true, presence: true, length: { maximum: 255 }
    validates :bb_at, presence: true
    validates :cc_id, presence: true
  end
```

exampleコントローラで以下のように条件分岐
```
if @ddd.valid?
    #メソッド
elsif @ddd.cscs?
    #メソッド
end
```
**この時、@ddd.valid?でfalseが出るとelsifの方に行かずメソッドが止まります。**
KeePassXC 2.7.9 が Windows 11 で起動しなかった時に行った対処（＋余談： パスキー関連の話）

自分がパスワード管理に活用している仕組みの 1つで、パスワード管理アプリが Windows・Mac のどちらでも使える「[KeePassXC](https://keepassxc.org/)」の話です。

![スクリーンショット 2024-11-02 162349.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/2b21ca8c-0588-3046-4973-54758782ae30.png)

新しくセットアップした PC で、新規に KeePassXC を入れた時にインストール後のアプリ起動ができない状態だったのを解決した際のメモです。

●Download – KeePassXC
 https://keepassxc.org/download/#windows

![スクリーンショット 2024-11-02 162633.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/8ff2992b-b84e-5bb2-e016-3f9295fef604.png)

## 解決方法
解決した方法は、 [MSVC Redistributable](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170) のインストールです。

これをインストール後に、再度 KeePassXC を起動しようとしたところ、無事にアプリを起動できました。

### 情報元
情報元は、検索して出てきた以下の中で見かけたものでした。

●can't run KeePassXC on Windows 11 : r/KeePass
 https://www.reddit.com/r/KeePass/comments/1e0l3n9/cant_run_keepassxc_on_windows_11/?rdt=41911

具体的には、以下の回答です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/72bcb568-860d-a48c-5997-5e741f010223.png)

## 後から気がついたこと
この記事を書くために、あらためて KeePassXC のダウンロードページを見た際に、以下の注意書きが書いてあるのに気がつきました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/459efc34-5cdb-893b-6df7-a4638130e30f.png)

こちらを見ると、2.7.9 で問題が発生しているという話と、その際の対処方法は「MSVC Redistributable」の再インストールというのが書いてありました。

## 余談： パスキー関連
余談です。

今回の記事を書く中で KeePassXC に関する検索をしていたところ、パスキー対応の話が出てきました。

●実装に1年、「KeePassXC」が待望の「パスキー」対応 ～フリーのパスワード管理アプリ - 窓の杜
 https://forest.watch.impress.co.jp/docs/news/1575337.html

前に情報を見かけた気がするものの、詳細を見ていなかったものです。

### 具体的な内容
最近、パスキーをよく使うようになったので、あらためて上記を見てみようと思います。

記事を見ると、KeePassXC でパスキーを使うには、拡張機能を導入する必要があるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/7b68242b-a03a-b24d-df1b-ae334210634c.png)

それに加えて Webブラウザの拡張機能をインストールして使う形になるようです。
今後、使い勝手などを、あらためて確認できればと思います。
Nmapによるポートスキャンの実行

# はじめに

以前に[簡易的なポートスキャナ](https://qiita.com/nkojima/items/852a2d5a3d8fddf548d5)を作ってみましたが、やはりちゃんとしたツールを使ってみようということで、試しにNmapを使ってみた時の記録を記事としてまとめてみました。

# 使用した環境

* 今回は手軽に試してみたかったので、WSL2環境を利用しました。

# Nmapのインストール

* WSL環境でUbuntuを使っているため、`apt-get`で簡単にインストールできました。
  * RHEL系でも`dnf install nmap`でインストールできるようです。

```shell-session
# apt-get install nmap
```

# Nmapの利用

## 最も簡単な使用方法

* `nmap {IPアドレス}`と指定するだけで、簡単にポートスキャンを実行できます。
  * ここでは22番と80番のポートが開放されていました。
* このようにオプションを付けずに実行すると、代表的な1000ポートを選んでスキャンを実行してくれるようです。
  * 最初はオプションなしの「お任せモード」で試してみるのが良いと思います。

```shell-session 
# nmap xxx.xxx.xxx.xxx
Starting Nmap 7.80 ( https://nmap.org ) at 2024-09-11 15:05 JST
Nmap scan report for ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com (xxx.xxx.xxx.xxx)
Host is up (0.082s latency).
Not shown: 998 filtered ports
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http
Nmap done: 1 IP address (1 host up) scanned in 10.96 seconds
```

## スキャンするポート番号を指定する

* 以下は`-p 1-65525`というオプションを指定して、1番～65535番までのポートをスキャンしています。
* スキャンするポートを増やすと当然ながらスキャン時間が長くなるので、この辺りは上手く調整しながら使うのが良さそうです。

```shell-session
# nmap -p 1-65535 xxx.xxx.xxx.xxx
Starting Nmap 7.80 ( https://nmap.org ) at 2024-09-11 15:34 JST
Nmap scan report for ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com (xxx.xxx.xxx.xxx)
Host is up (0.013s latency).
Not shown: 65533 filtered ports
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http
Nmap done: 1 IP address (1 host up) scanned in 104.60 seconds
```

## バージョンのスキャン

* `-sV`オプションを付けることで、バージョンスキャンを行うことができます。
* 以下の例だと、Apacheについてはhttpd.confの設定を変えているのでバージョンが表示されていませんが、OpenSSHについてはバージョンが表示されています。

```shell-session
# nmap -sV xxx.xxx.xxx.xxx
Starting Nmap 7.80 ( https://nmap.org ) at 2024-11-02 16:36 JST
Nmap scan report for ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com (xxx.xxx.xxx.xxx)
Host is up (0.024s latency).
Not shown: 997 filtered ports
PORT    STATE  SERVICE VERSION
22/tcp  open   ssh     OpenSSH 8.7 (protocol 2.0)
80/tcp  open   http    Apache httpd
443/tcp closed https

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 12.42 seconds
```

# 参考URL

* [書籍：インフラエンジニア教本――セキュリティ実践技術編](https://www.amazon.co.jp/dp/4774189243)
[Swift] AppStorageとUserDefaultsについて

## 1. AppStorageとUserDefaultsの概要
AppStorageは、SwiftUIで使える便利な仕組みで、@プロパティラッパーとして簡単にユーザーデフォルトにデータを保存したり読み込んだりできます。UserDefaultsを裏で使っているため、SwiftUIのコードがよりシンプルに書けます。

UserDefaultsは、アプリ全体でKey-Valueの形でデータを保存できる仕組みです。アプリを再起動しても保存したデータを保持して、自動的に読み込むことができます。

つまり、AppStorageもUserDefaultsも基本的な機能は同じですが、AppStorageの方がSwiftUIと組み合わせて使うときにコードがスッキリするのが特徴です。

## 2. 基本データ型とサポート内容
**AppStorage**がサポートする基本データ型:
- **Bool、String、Data、Int、Double、URL**
- **RawRepresentable**に準拠し、RawValueが**String**または**Int**の型も保存可能

**UserDefaults**も多くの型をサポートしますが、保存できるデータは基本的に**Plist**形式（**NSData、NSString、NSNumber、NSDate、NSArray、NSDictionary**）のみです。

## 3. 使い方の簡単な例
```swift
// AppStorageの使用例
struct ContentView: View {
    @AppStorage("username") private var username: String = "ゲスト"

    var body: some View {
        VStack {
            Text("こんにちは、\(username)さん！")
            Button("名前を変更") {
                username = "田中"
            }
        }
    }
}

```

```swift
// UserDefaultsの使用例
struct ContentView: View {
    @State private var username: String = UserDefaults.standard.string(forKey: "username") ?? "ゲスト"

    var body: some View {
        VStack {
            Text("こんにちは、\(username)さん！")
            Button("名前を変更") {
                username = "田中"
                UserDefaults.standard.set(username, forKey: "username")
            }
        }
    }
}

```

## 4. 読み取り時の注意事項
読み取り時の注意事項 UserDefaultsから値を読み取るとき、BoolやIntにはデフォルトの戻り値があるため、指定したキーが存在しない場合でもfalseや0が返されます。
## 5. その他のデータ保存手法

| 手法          | 機能            | 適用データ           | 特徴                                   |
|---------------|-----------------|----------------------|----------------------------------------|
| **UserDefaults** | Key-Value型    | 小規模なデータ       | 素早いアクセスが可能。<br>ただしセキュリティ面には注意が必要。 |
| **FileManager**  | ファイル保存     | 大規模または複雑なデータ | 柔軟性が高いが、ファイル管理がやや複雑。               |
| **CoreData**     | SQLiteを使用    | リレーショナルデータ | データの検索・操作が容易で、<br>複雑な構造にも対応可能。     |
| **KeyChain**     | セキュア保存     | パスワードやトークン  | 安全性が高く、機密情報の保存に最適。                  |

#### 注意事項
- **UserDefaults** は基本的に小規模な設定データを保存するのに向いており、読み取り時にBoolやIntのデフォルト値が返されるため注意が必要です。
- **FileManager** はファイル単位でのデータ管理が可能ですが、ファイルパスやアクセス権限の管理を慎重に行う必要があります。
- **CoreData** は複雑なデータ構造やリレーショナルデータの保存に適しており、データの検索やフィルタリングが容易です。
- **KeyChain** はセキュリティの高い情報（例：パスワード、認証トークン）の保存に使用され、iOSデバイス間の共有も可能です。

## 結論
小規模な設定や状態管理にはAppStorageやUserDefaultsを使用し、注意が必要な場面では戻り値や型の特性を考慮しましょう。
セキュリティが求められるデータはKeyChainを、複雑なデータ構造や大量のデータ保存にはCoreDataを使い分けることが重要です。
【AWS EC2】SessionManagerで接続できなくなったときのメモ

# はじめに
　いつも、EC2インスタンスに対してSessionManagerで接続してアレコレやっています。
　この前「とある**EC2インスタンスで動かしているwebアプリの挙動がおかしい**（ログイン画面にアクセスしても500エラーが表示された）」上に、「**SessionManagerを用いて対象EC2への接続を試みたものの、**
```
セッションが次の理由で終了されました。 Plugin with name Standard_Stream not found. Step name: Standard_Stream
```
という**エラーが出て接続ができない**」ということがあったので、そのときの対応内容に関してざっくりとメモを残します:ram:

:warning: システムによって必要な情報が異なる箇所もあるので、以下はざっくりと書いています。
:warning: ググって見つかる方法より少しだけ丁寧めに書けているかな～とは思います。
:warning: **こちらは社内に2023年4月頃に公開したメモを少しだけ整えたものです。** 

## そもそも…なんでSessionManagerで接続しているの？
　この方法での接続ですと、下記のようなセキュリティ面でのメリットがあります↓
- EC2に余計なポートを空ける必要が無い
- 鍵管理が不要

　ただ、この方法…**SessionManagerはEC2内でアプリが起動しているらしく、その起動分の容量がEC2に無いと接続できない**らしいとのこと（受け売りコピペ）。

　また、SessionMangerを用いるにははじめにインストール等の手間もかかるので、例えば「案件内で多数のEC2を扱っている」場合はなかなか難しいと思います。

# 今回の繋がらなくなった原因は？
 **容量不足** である ことが多いみたいです（ググったら大抵そんな理由だった）

# 今回実施した対応内容

## 1.  （仕方なく）該当のEC2のセキュリティグループにて一時的にsshの穴を開ける

### ①対象のEC2のセキュリティグループのインバウンドルールを表示
### ②社内IPアドレスからのアクセスでsshを許可する
※EC2経由でアクセスする場合はEC2のセキュリティグループのsshを許可する

## 2. ローカルからツールを使ってsshでアクセスする
RLoginやPutty、Teratermなどを使ってアクセスしましょう。

## 3. 調査＆対処…容量を食っている部分を確認して、削除できるものがあれば削除する
### ①どこのボリュームに問題があるのか確認する　※使用率を確認する
```
df -h
```

### ②問題のあるボリュームに移動して各フォルダの容量を確認して使用量の高いフォルダを確認する 
```
cd 【問題のあるボリューム】
du -sh ./*
```
※この作業を繰り返してフォルダを特定する

### ※容量が大きくなるフォルダの傾向とその対処法
#### ▼ Docker関連
- Dockerの使用していないコンテナ・イメージを削除する
```
docker container prune
docker image prune
```
- Dockerの使用していないイメージ、コンテナ、ネットワークを削除する
```
docker system prune
```
- ボリュームも削除する場合は以下
```
docker system prune --volumes
```
#### ▼ ログ
　肥大化しやすいログがあるのなら要注意。
　ログに対しては、圧縮や、古いファイルの削除等を実施する可能性があります。
- ファイルのサイズを変更する
```
truncate -s サイズ ファイルパス
```

（が、ログローテートなど管理方法・ルールを見直して、そもそものログ肥大化の再発を防止した方が良いでしょう…）

# おわりに
　作業中、対応内容3. の容量を食っている部分に関して「ほんとに削除していいのか？」と悩むことがありました。加えて、そもそものログ設計がしっかりしていたり、ログの管理ルールをしっかりしていれば防げるところもあったのかな～なんて。
　ということで、今回の方法はあくまで暫定対応。はじめから良い設計ができていれば良いに越したことは無いでしょうが、起きてしまった際は良い機会だと思って設計・運用の見直しを実施したいですね。暫定対応だけ実施してその後放置→再発、が無いように！

　より良い方法やツッコミ、その他もろもろ何かありましたら是非お気軽にコメント等くださいませ～！:pray::pray:
Ubuntuのバックアップツール(deja dup)で見えないディレクトリを除外する方法

## 対処したい問題

Ubuntu24.04 Desktopではバックアップツールが最初からインストールされており、左下のメニューからのユーティリティの中に「バックアップ」があります。この実体はDeja Dupというツールです。

![Screenshot from 2024-11-02 15-39-35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602324/42e5ca7c-4aba-b4d9-d9a9-8ecfad3319fc.png)

このツールの設定で、バックアップ対象から除外するディレクトリを指定する機能があります。デフォルトではホームディレクトリ全体が対象に入っていますが、私の場合は ~/.pyenv や ~/.rustup に pythonとrustを入れており、これらが計2GBを占めるので、容量&時間節約のためバックアップ対象から除外したい。

ところが、このツールで除外ディレクトリを指定しようとすると、見えないファイル（'.'で始まる、単にlsでは見えず、ls -aでないと見えないもの）は一覧に出てこないのです。なので ~/.pyenv などは選択できない。

![Screenshot from 2024-11-02 15-51-56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602324/c2739f1a-8341-5f74-78d8-ec8207265640.png)

(↑ .pyenvなどは出てこない)

本記事は、この問題にどう対処するか、という話になります。

## 解決策

結論から書きます。dconf-editorというツールを使って、除外ディレクトリをテキストで指定します。

dconfについては、詳しくはたとえば[こちら](https://kledgeb.blogspot.com/2012/12/ubuntu-dconf-1-dconf.html)の記事を参照ください。簡単に言うと、「dconfはソフトウェアの設定を保存するシステムで、Windowsで言うところのレジストリみたいなもの」だそうです。

以下、手順です。まずaptで dconf-editor をインストールします。

```
sudo apt install dconf-editor
```

その後ターミナルから'dconf-editor'と入れると、GUIの画面が出てきます。

![Screenshot from 2024-11-02 16-04-35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602324/ca0ad2c3-237b-9072-ac2c-46a87f6abde2.png)

ここから org  -> gnome -> deja-dup -> exclude-list の順に行くと、下のような画面になります。ここの「カスタム値」のところに直接書くことができます。

![Screenshot from 2024-11-02 16-07-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602324/3ffd0d77-e530-757b-bd06-a94c0a84a28a.png)

簡単ですが、説明は以上です。

## 参考

この解決法は、いろいろ検索していた中で、[こちら](https://askubuntu.com/questions/690990/can-i-ignore-files-by-pattern-in-deja-dup-backup)の記事で見つけました。
password_hash関数の落とし穴

# はじめに
この記事の対象はPHPを使ったシステムを使っている方向けの内容となります。
社内システムを1年くらい前にPHP8.2にアップデートしました。

直近まで「SHA-512」アルゴリズムによるハッシュ化は「hash関数」を利用していました。
しかし、セキュリティ対策を目的として「password_hash関数」を利用するように変更しました。
password_hash関数に変更をしたものの、問題が発生したためこの記事を残すことにします。

# 発生した問題
```password_hash関数が、大量データを一気にハッシュ化するようなシステムには適していなかった```
ということです。

社内システムには、1度に5,000件〜10,000件程度のデータをCSVインポートする機能があります。

この機能がhash関数を使っていたときは問題がなかったが、タイムアウトを起こすようになってしまったのです。

どこに原因があるのか調べてみたところ、hash関数とpassword_hash関数のパフォーマンスの違いが原因でした。

実際に、以下のプログラムを作ってパフォーマンスを計測してみました。

# 計測プログラム

```php:計測プログラム

$password = 'aaaaaaaaaaaaaaaaaa';

echo '------ hash関数 -----' . PHP_EOL;

$start_time = microtime(true);

$hashedPasswordSha512 = hash('sha512', $password);

echo "SHA-512 Hash: " . $hashedPasswordSha512 . PHP_EOL;

$end_time = microtime(true);

echo 'execute time: ' . ($end_time - $start_time) . PHP_EOL;


echo PHP_EOL;


echo '------ password_hash関数 --------' . PHP_EOL;

$start_time = microtime(true);

$hashedPassword = password_hash($password, PASSWORD_DEFAULT);

echo "Password Hash: " . $hashedPassword . PHP_EOL;

$end_time = microtime(true);

echo 'execute time: ' . ($end_time - $start_time) . PHP_EOL;
```

# 計測結果
- hash関数: 1.3E-5秒
- password_hash関数: 0.05秒


# 考察
hash関数のほうがpassword_hash関数の「100倍」程度高いパフォーマンスを出すことがわかりました。


つまり社内システムでインポートするデータ数が5,000件として、

処理が完了するのにかかる時間はそれぞれ

- hash関数: 0.065秒
- password_hash関数: 250秒

ということになります。

これではpassword_hash関数を利用した場合は、タイムアウトするのも当然ですね。

# さいごに

password_hash関数は同じ文字列を何度ハッシュ化しても絶対に同じハッシュ値とならないなど、セキュリティ面で優れており、かつpassword_verify関数なども合わせて利用することができるため、非常に便利であることに変わりはありません。

みなさんもpassword_hash関数を利用する際は気をつけてほしいとおもいます。
【面接対策】一貫性のあるストーリーを作るためのライフハック

# 私は今年、初めての転職をしました
面接対策について振り返ってみると、私が特に意識していたのは`ストーリーに一貫性があること`でした。では、一貫性のあるストーリーとはどのようなものでしょうか？

# 一貫性のあるストーリーとは？
私の考える`一貫性のあるストーリー`とは、**過去+現在が未来向かって一つの道筋となっていること**です。例えば次のような内容が挙げられます。
- 過去+現在
    - 過去、どのような体験、経験をしてきたか
    - 現在、どのような仕事、勉強、活動をしているか
    - 転職を考えたきっかけ
    - 志望企業に応募したきっかけ
- 未来
    - 将来の夢や理想像
    - 誰と、どんな風に働きたいか
    - 志望企業で実現したいこと

もし、これらに矛盾があった場合、面接官から「どこか嘘ではないか？」と疑われてしまうかもしれません。
そこで、今回は私が一貫性のあるストーリーを作るために使った方法を紹介します。

それは...

# 結論: 志望企業の「未来社員インタビュー」を勝手に執筆する
です！

企業の採用ページで「先輩社員インタビュー」をよく見かけますよね？

あれを、自分がその会社へ入社したつもりになって執筆してみてください！！(この社員インタビューを以下「未来社員インタビュー」と呼びます)

# 未来社員インタビューのフォーマット
社員インタビューは通常、以下のような流れかと思います。
* 自己紹介
    * どんなバックグラウンドがあるか
    * 現在、どのような仕事をしているか、何に興味関心があるか
* 企業を選んだきっかけ、決め手
* 将来の目標や、やりたいこと
* (読者へのメッセージ)

見覚えのある流れではないでしょうか？
そうです、社員インタビューも基本的に過去、現在、未来といった時間軸で語られます。未来社員インタビューも、このフォーマットに従いましょう。それだけで一貫性のあるストーリーが作れるという目論みです。

さらに、未来社員インタビューには他にも様々なメリットがあります。
最後にこれらメリットについて述べていきます。

# メリット1: 企業分析が捗る
(自称)自社のことを語るには当然、(自称)自社のことを知らなければいけません！調べましょう！！

例えば、会社設立の経緯、事業内容を理解することで志望意欲が更に増すかもしれないですね。また、採用ページや求人内容の詳細を見ることで、働くイメージが湧いてくるのでは無いでしょうか？

企業に対する興味や理解が深まることによって、志望動機をより具体的に伝えることができるようになりますし、その他の質問に対する回答にも自信が持てるようになるはずです。

# メリット2: 自然と逆質問の内容が出てくる
面接での逆質問、何を聞けば良いか分からなくて困りますよね。一方で、未来社員インタビューを書いていると、「ここがもっと知りたい！」と思う点が自然と出てくるはずです。

例えば、採用ページでは語られていない「社長や役員が抱えている課題は何か？」であったり、「どのような成長が期待されているか？」など、知りたい情報があれば、逆質問で聞いちゃいましょう！

これは、単なる形式的な質問ではなく、本当に知りたいと思っている質問になるので、面接官にも熱意が伝わるはずです。

# メリット3: 入社後の行動が明確になる
無事に内定を頂いて、入社する頃には未来社員インタビューは完成していることでしょう。
その中で、「将来の目標や、やりたいこと」にあなたは何を書いたでしょうか？

**是非、その目標に向かって次のアクションを実行してみてください！！**
【ChatGPT】コミットメッセージを生成するMyGPTを作ってみた

## はじめに

こんにちは、かなたです。
個人開発を進めている中で「適切なコミットメッセージの作成」に悩みました。
変更内容を簡潔に正確に表現するには意外に時間と労力がかかります。
そこで、ChatGPTを活用してコミットメッセージを生成するMyGPTを作りました。

## 作ったもの
 
https://chatgpt.com/g/g-5yr5VxPFq-git-commit-metusesiasisutanto

上記のリンクから利用できます。

## 使い方

### 1. 差分ファイルの作成

ファイルの変更内容をステージングして差分ファイルを生成します。

```bash
git add [ファイル名]
git diff --cached > diff.txt
```

### 2. GPTとの会話
Git Commit メッセージアシスタントを使用します。
1. アシスタントを開く
2. 生成した`diff.txt`ファイルをアップロード
3. 生成されたコミットメッセージを確認

### 3. コミットの実行

変更内容をコミットします。

```bash
git commit
```


## MyGPTの作成方法

備忘録を兼ねて「Git Commit メッセージアシスタント」の作り方を共有します。

1. ChatGPT を開いて左側のメニューから「GPTを探す」を押します
2. 右上の「作成する」ボタンを押します
3. GPTとの対話画面が表示されたら、次の指示を入力します

```
■指示１
あなたはGitのステージングされた差分ファイルを元に、指定の形式でコミットメッセージを生成するアシスタントです。
ファイルがアップロードされたら、以下のフォーマットでメッセージを作成してください。

- タイトル（1行目）は英語
- 本文（3行目以降）は日本語で詳細を記述

■指示２
アシスタントであるあなたは日本語で応答してください。

■指示３
返信のフォーマットのサンプルを以下に記載します。

　```
Title

・本文
・本文
・本文
・本文
・本文
・本文
　```

■指示４
あなたはコンセプトに沿ったロゴを描いて自身に設定してください。

■指示５
あなたの名前は「Git Commit メッセージアシスタント」としてください。

```


## おわりに

今回は個人開発を進める中での需要に応じたMyGPTを作りました。
大前提、誰しも当たり前に使いこなせているMyGPTですが、この記事が何かの為になったら嬉しく思います。
それではさよなら。
laravel reverbをSSL化する方法

# 前提条件
- laravel11
- nginx
# .envファイルの設定
```
REVERB_APP_ID=my-app-id
REVERB_APP_KEY=my-app-key
REVERB_APP_SECRET=my-app-secret
REVERB_HOST="my-app-host"
REVERB_PORT=443
REVERB_SCHEME=https

VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
VITE_REVERB_HOST="${REVERB_HOST}"
VITE_REVERB_PORT="${REVERB_PORT}"
VITE_REVERB_SCHEME="${REVERB_SCHEME}"
```
.envファイルに上記の設定を追加してください。
ただし`my-`から始まるところは任意の値に書き換えてください。
# nginxの設定
```
 location /app {
        proxy_http_version 1.1;
        proxy_set_header Host $http_host;
        proxy_set_header Scheme $scheme;
        proxy_set_header SERVER_PORT $server_port;
        proxy_set_header REMOTE_ADDR $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";

        proxy_pass http://0.0.0.0:8080;
    }
```
nginxに上記の設定を追加してください。
`/app`の部分は`/`にするとうまくいきませんでした。
これはlaravel reverbサーバーをデフォルトの設定で動かした時の設定です。
# さいごに
laravel reverbサーバーをバックグラウンドで動かすにはsupervisorを使用しましょう。
方法はchatGPTに聞けば教えてくれます。
python仮想環境のディレクトリ備忘録

##### 普通のインストールとvenvの仮想環境のインストールの比較

venvではvenv/bin/pythonが../lib/python3.9/pythonのシンボリックリンクになっている
~~~
/  # ルートディレクトリ
├── usr/
│   └── local/
│       └── lib/
│           └── python3.8/  # システム全体にインストールされたPython 3.8
│               ├── bin/
│               └── lib/
├── home/
│   └── user/
│       └── myproject/
│           └── venv/  # venvで作成した仮想環境
│               ├── bin/
│               │   ├── activate
│               │   ├── python -> ../lib/python3.9/python
│               │   └── ...
│               └── lib/
│                   └── python3.9/
│                       ├── site-packages/
│                       └── ...
~~~

#### 普通のインストール+condaのenvでのインストール+venvでのインストール
~~~
/
├── usr/
│   └── local/
│       └── lib/
│           └── python3.8/  # システム全体にインストールされたPython 3.8
│               ├── bin/
│               └── lib/
├── home/
│   └── user/
│       ├── miniconda3/  # Anaconda/Minicondaのインストールディレクトリ
│       │   └── envs/
│       │       ├── my_conda_env_3.9/  # Python 3.9 のconda環境
│       │       │   ├── bin/
│       │       │   └── lib/
│       │       └── my_conda_env_3.10/  # Python 3.10 のconda環境
│       │           ├── bin/
│       │           └── lib/
│       └── myproject/
│           ├── venv/  # venvで作成した仮想環境 (Python 3.9)
│           │   ├── bin/
│           │   │   ├── activate
│           │   │   ├── python -> ../lib/python3.9/python
│           │   │   └── ...
│           │   └── lib/
│           │       └── python3.9/
│           │           ├── site-packages/
│           │           └── ...
│           └── venv3.10/  # venvで作成した仮想環境 (Python 3.10)
│               ├── bin/
│               │   ├── activate
│               │   ├── python -> ../lib/python3.10/python
│               │   └── ...
│               └── lib/
│                   └── python3.10/
│                       ├── site-packages/
│                       └── ...
~~~
CSSを学びたい Step10 画像にぼかしや色を調整する

## はじめに
CSSを学びたいStep10です。今回は画像にぼかしや色を調整できる**filter**に関して学んでいきます

## 成果物
![スクリーンショット 2024-11-02 15.37.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/5864d836-f5c1-707e-8a0e-7304f6eb2ec4.png)

→ぼかしや色が変わっていますよね！全て同じ画像ですが、CSSで修正が加えられます！！

## ソースコード
```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Filter Property Example</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="filter-examples">
        <img src="example.jpg" alt="Original Image">
        <img src="example.jpg" alt="Blur Effect" class="filter-blur">
        <img src="example.jpg" alt="Brightness Effect" class="filter-brightness">
        <img src="example.jpg" alt="Contrast Effect" class="filter-contrast">
        <img src="example.jpg" alt="Grayscale Effect" class="filter-grayscale">
        <img src="example.jpg" alt="Invert Effect" class="filter-invert">
        <img src="example.jpg" alt="Saturate Effect" class="filter-saturate">
        <img src="example.jpg" alt="Sepia Effect" class="filter-sepia">
        <img src="example.jpg" alt="Drop Shadow Effect" class="filter-drop-shadow">
    </div>
</body>
</html>
```

```css:styles.css
.filter-examples img {
    width: 200px;
    height: auto;
    margin: 10px;
}

/* ぼかし効果 */
.filter-blur {
    filter: blur(5px);
}

/* 明るさ効果 */
.filter-brightness {
    filter: brightness(150%);
}

/* コントラスト効果 */
.filter-contrast {
    filter: contrast(200%);
}

/* グレースケール効果 */
.filter-grayscale {
    filter: grayscale(100%);
}

/* 反転効果 */
.filter-invert {
    filter: invert(100%);
}

/* 彩度効果 */
.filter-saturate {
    filter: saturate(200%);
}

/* セピア効果 */
.filter-sepia {
    filter: sepia(100%);
}

/* ドロップシャドウ効果 */
.filter-drop-shadow {
    filter: drop-shadow(10px 10px 5px rgba(0, 0, 0, 0.5));
}
```
CSSを学びたい Step9 Transition、Transform

## はじめに
CSSを学びたいのStep9です！！今回はTransition、Transformに関して学ぼうと思います！！

## Transitionとは
状態が変わるときにスムーズにアニメーションすることで、自然な動きを演出します。ホバー時やクリック時のエフェクトに頻繁に使われます。

## Transformとは
要素を回転、拡大縮小、移動、斜め変形することができます。特にアニメーションと組み合わせると、インタラクティブで面白い効果が作れます。

## 成果物
![transition.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/4d069c71-47b5-dcf8-574a-3c1811391bc3.gif)

## ソースコード

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Transition Example</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <button class="transition-button">Hover me!</button>
</body>
</html>
```

```css:styles.css
.transition-button {
    padding: 10px 20px;
    font-size: 16px;
    background-color: #3498db;
    color: #fff;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    transition: background-color 0.3s ease, transform 0.3s ease;
}

.transition-button:hover {
    background-color: #2ecc71; /* ホバー時に背景色を変更 */
    transform: scale(1.1); /* ホバー時にサイズを拡大 */
}
```