OmniAICreator/Qiita-1.07M huggingface dataset:
PC起動時にWebDriverを自動でダウンロード更新したい

## はじめに
WebDriverを使用していたら、ある日突然ブラウザの更新が入ってしまいエラーが発生してしまうなんてことありませんか？その度にブラウザのバージョンを確認してそのバージョンにあったWebDriverをダウンロードするのが案外手間だったりします（実際、私は手間でした・・・）。なので、PC起動時にWebDriverのダウンロードと更新を自動化するプログラムを作成しました。

## 処理
WebDriverのダウンロードと解凍処理の流れは以下です。

```visualbasic
Private Sub DownloadWebDriver(ByVal BrowserVersion As String)

    Dim DownloadUrl As String = 
        String.Format("https://storage.googleapis.com/chrome-for-testing-public/{0}/win64/{1}", BrowserVersion, "chromedriver-win64.zip")
    Dim ZipFilePath As String = Path.Combine(DownloadPath, CHROME_DRIVER_ZIP_FILE)

    Try
        Using HttpClient As New HttpClient()

            'Byte型配列にダウンロードデータを格納
            Dim FileBytes As Byte() = HttpClient.GetByteArrayAsync(DownloadUrl).Result

            If Not Directory.Exists(DownloadPath) Then
                Directory.CreateDirectory(DownloadPath)
            End If

            'ダウンロードデータをzipファイル形式に書き出す
            File.WriteAllBytes(ZipFilePath, FileBytes)

        End Using

        'zipファイルの解凍
        Me.ExecuteUnZip(ZipFilePath)

    Catch ex As Exception
        Console.WriteLine(ex.Message)
    End Try
End Function

Private Sub ExecuteUnZip(ByVal ZipFilePath As String)
    Try
        Dim WebDriverPath As String = Path.Combine(DownloadPath, "chromedriver-win64", "chromedriver.exe")

        If File.Exists(WebDriverPath) Then
            File.Delete(WebDriverPath)
        End If

        'zipファイルの解凍処理
        ZipFile.ExtractToDirectory(ZipFilePath, DownloadPath, True)
        File.Delete(ZipFilePath)

    Catch ex As Exception
        Console.WriteLine(ex.Message)    
    End Try
End Function
```

HttpClientクラスを使って指定のURLからWebDriverをダウンロードして、ZipFileクラスでダウンロードしたZipファイルを解凍する流れになります。これでダウンロードから圧縮ファイルの解凍までできました。
ですが、このプログラムをスタートアップフォルダに格納するとOS起動時に毎回ダウンロードしてしまいます。それですと、無駄なダウンロード処理が発生してしまうため、現在のブラウザのバージョンと保存しているWebDriverのバージョンが不一致の時だけダウンロードするようにしました。ブラウザのバージョンはレジストリで持っているので、そこから値を持ってきています。

~~~visualbasic
Private Function GetWebBrowserVersion() As String

    Dim RegData As RegistryKey = Registry.CurrentUser.OpenSubKey("レジストリキーの階層を指定する")

    Return RegData.GetValue("Versionのパラメータを指定する").ToString()

End Function
~~~

ブラウザのバージョンが取得出来たら、あとは設定ファイルなどに持たせてあるWebDriverのバージョンと比較してあげればよさそうですね。


## さいごに
以上がQiita初投稿になります。
プログラミングにそんなに詳しくないので作りが拙い部分もあるかもしれません。ご指摘大歓迎なのでコメントいただけると助かります！（勉強させてください）
npmでビルドしてGitHub PagesにデプロイするActionsテンプレート配布します

:::note info
GitHub PagesのことをGHPと呼んでいます。
:::

## きっかけ
時々ViteでWebツール作ってGHPに公開したりしてました。
しかし自分はビルドしたページの内容をGitHubにプッシュして
Static htmlのテンプレからGHPにデプロイしてました。

しかしnpmをつかってbuildとかをActionsに任せられるそうなので
distをignoreしてActionsに任せられるようになりました。

## Actionsとは？
GitHubActionsです。これは、GitHubにプッシュすると指定されたコマンド(?)を
自動でしてくれる、実質プッシュごとに面倒なことをしてくれるロボットですね。

`npm run build`してGHPにデプロイするなんて簡単すぎます。

:::note alert
GitHubが無料プランの場合Actionsは月に2000分のみ、
1日換算では1時間ぐらいしか使えません。
プッシュを控えるなど、ご利用は計画的に。

有料プラン等の詳細はこちら。
:::

https://qiita.com/39ra8/items/fd26e68d00b61b922ca2#private-%E3%81%AA%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E7%84%A1%E6%96%99%E6%9E%A0%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6

## テンプレ
:::note warn
これを実行する際は、リポジトリのSetting→Pages→Build and deploymentのSourceをGitHub Actionsにする必要があります。
:::

```yml:deploy.yml
name: Deploy page
on:
  push:
    branches: ["main"]
permissions:
  contents: read
  pages: write
  id-token: write
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm install
      - run: npm run build
      - uses: actions/configure-pages@v5
      - uses: actions/upload-pages-artifact@v3
        with:
          path: './dist' # サイトとして出力するパスを指定してね
      - uses: actions/deploy-pages@v4

```

## 解説
1. チェックアウトしてGitHubのコンピューター内(?)に自分のリポジトリの内容を置きます
1. nodejsをインストール(?)します
1. npmで依存関係をインストールします
1. npmでサイトをビルドします(package.jsonで指定すればお好みの動作が可能)
1. GHPのセットアップ・アップロード・デプロイをします

以上です。
ご自由にお使いください。
【Python】文字をペイント系ソフトのペンツールで描画する

# なぜ作ろうと思ったか
とあるサイトで、画面にマウスや指、アップルペンシルなどを使って描画したものをサーバーに送信できる機能がありました。自分はwindowsを使っているのでマウスでしか描画できません。そうした際に文字をきれいに描画することができないという問題が発生します。そういった問題を解決するため、このツールを作成することとしました。

# 制作過程とコード配布
pythonにあるpyautoguiとpillowというライブラリを組み合わせて作ることとしました。

pypiを使ったライブラリのインストールコマンド
```
pip install pyautogui pillow
```

ChatGPTが作ったコードを改良しただけではありますが、完成形を配布します！
＊テキストとttfフォントへのパスは自分で指定してください。
(動作確認済みの環境：python 3.10)
```py
import pyautogui
import time
from PIL import Image, ImageDraw, ImageFont

# 手書き風に描くテキスト
text = "描画するテキスト"
font_size = 48

# 手書き風に描くために使うフォントの設定
# 適当な手書き風フォントファイル（.ttf）を指定してください
font_path = "ttfフォントファイルへのパス"
font = ImageFont.truetype(font_path, font_size)

# テキストのサイズを取得
bbox = font.getbbox(text)
text_width, text_height = bbox[2] - bbox[0], bbox[3] + bbox[3]

# キャンバスの作成
image = Image.new("L", (text_width, text_height), 255)
draw = ImageDraw.Draw(image)
draw.text((0, 0), text, font=font)

# テキスト画像のピクセル情報を取得
pixels = image.load()

# 手書きするペイントアプリのキャンバスの左上位置を指定
start_x = 1000  # 開始位置のx座標
start_y = 300  # 開始位置のy座標

# 白以外の（手書きの軌跡が見える）ピクセルのリストを取得
positions = []
for y in range(text_height):
    for x in range(text_width):
        if pixels[x, y] < 200:  # 黒色または灰色のピクセルを取得
            positions.append((start_x + x, start_y + y))

# 描画位置の確認のために最後の位置を表示（デバッグ用）
print("Last position:", positions[-1])

# 取得したピクセル位置を手書きで描画する
pyautogui.PAUSE = 0.005  # 軌跡をゆっくりにするためのポーズ
pyautogui.click(start_x, start_y)  # ペイントキャンバス上をクリックしてアクティブ化
for position in positions:
    pyautogui.moveTo(position[0], position[1])  # マウスを移動
    pyautogui.click()  # クリックして描画

# 描画の終了
pyautogui.mouseUp()
```
# 動作例
動画で見たほうが早いと思うので、動画を張っておきます。
(描画を滑らかにするためにゆっくり少しずつ描画しており、GIFが長すぎるため8倍速です)
![text2draw_example.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931095/b9f69a16-4f86-6b7e-63b5-36840322a094.gif)


# 問題点
- 異なる**テキスト**を描画する際に毎回コードを編集する必要がある
- 異なる**フォント**で描画する際に毎回コードを編集する必要がある
- 描画中に描画を停止できない (コードの改良で簡単に実現できそう...?)
- 描画が非常に遅い

# まとめ
あまり実用性はなさそうですが、自分は冒頭で述べたサイトをよく使うため、時々使っています。
問題点で述べた点については簡単に改善できそうですが、自分はあまり気にならないのでまだ改良していませんが、また改良したらコードを共有しようと思っています。
アルゴリズム勉強

# 内容・目的
　[テキスト](https://www.amazon.co.jp/%E5%95%8F%E9%A1%8C%E8%A7%A3%E6%B1%BA%E5%8A%9B%E3%82%92%E9%8D%9B%E3%81%88%E3%82%8B-%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0-KS%E6%83%85%E5%A0%B1%E7%A7%91%E5%AD%A6%E5%B0%82%E9%96%80%E6%9B%B8-%E5%A4%A7%E6%A7%BB-%E5%85%BC%E8%B3%87/dp/4065128447/ref=pd_sbs_d_sccl_3_2/357-2934504-0673537?pd_rd_w=7b1RL&content-id=amzn1.sym.cc4f782f-18e8-4959-acfc-ffdf7905539a&pf_rd_p=cc4f782f-18e8-4959-acfc-ffdf7905539a&pf_rd_r=HANHS3CND16A1SS3FJ37&pd_rd_wg=2PMm3&pd_rd_r=e4925f2a-1b25-47b7-868e-5e9c5abd510d&pd_rd_i=4065128447&psc=1)の5章1問目に関して理解を深めるとともに文章能力，言語能力を向上させるためにoutputとしてこの記事を作成した.
AtCoderの緑レート目指して頑張る．

## 内容・概要
[問題](https://atcoder.jp/contests/dp/tasks/dp_c)
この問題を読んだ時に考えた解法はforg問題の発展形のように予測し，frog問題の解法を元に制約をつけ加えた問題として仮定した.
問題の制約としてネックだったのは，同じ選択(a,b,c)を選んではならないという点だった. そのことから３日間の合計が最大となるように取ればよいのではないかと予測し，解を求めようとして失敗した.

その後回答のコード(c++)をGminiでpythonに変換させコードの解読と解釈をしたものを下記に示す.
```python
def solve(N, a):
    dp = [[0] * 3 for _ in range(N + 1)]

    for i in range(N):
        for j in range(3):
            for k in range(3):
                if j != k:
                    dp[i + 1][k] = max(dp[i + 1][k], dp[i][j] + a[i][k])

    return max(dp[N])
# 解く
ans = solve(N, a)
print(ans)
```
 このコードがやっていることはdpテーブルを作製するとき，各dpテーブルの仮にi番目でのa,b,cでの最大値を取るようにしている．そのようにすることでi+2の時にa,b,cのどれでも結果的に最大を求めることが出来るからだ．

## 参考・引用
[問題AtCoder](https://atcoder.jp/contests/dp/tasks/dp_c)
[アルゴリズムとデータ構造](https://www.amazon.co.jp/%E5%95%8F%E9%A1%8C%E8%A7%A3%E6%B1%BA%E5%8A%9B%E3%82%92%E9%8D%9B%E3%81%88%E3%82%8B-%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0-KS%E6%83%85%E5%A0%B1%E7%A7%91%E5%AD%A6%E5%B0%82%E9%96%80%E6%9B%B8-%E5%A4%A7%E6%A7%BB-%E5%85%BC%E8%B3%87/dp/4065128447/ref=pd_sbs_d_sccl_3_2/357-2934504-0673537?pd_rd_w=7b1RL&content-id=amzn1.sym.cc4f782f-18e8-4959-acfc-ffdf7905539a&pf_rd_p=cc4f782f-18e8-4959-acfc-ffdf7905539a&pf_rd_r=HANHS3CND16A1SS3FJ37&pd_rd_wg=2PMm3&pd_rd_r=e4925f2a-1b25-47b7-868e-5e9c5abd510d&pd_rd_i=4065128447&psc=1)
[Ruby][Python] 任意の文字を Unicode コードポイント (U+1234 という形式) に変換する

## やりたいこと

任意の文字を Unicode コードポイント (U+1234 という形式) に変換したいです。

![U+1234](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6697/2f779430-32cd-f6d5-243a-43a443b52913.png)
🔼 https://www.compart.com/en/unicode/U+1234 より

Ruby と Python それぞれでの方法を紹介します。

## Ruby

[String#ord](https://docs.ruby-lang.org/ja/latest/method/String/i/ord.html) と [String#%](https://docs.ruby-lang.org/ja/latest/method/String/i/=25.html) を使います。

```shell-session
$ ruby -v
ruby 3.3.6 (2024-11-05 revision 75015d4c1f) [arm64-darwin24]
```

```rb
char = 'カ'
'U+%04X' % char.ord
#=> "U+30AB"

char = '力'
'U+%04X' % char.ord
#=> "U+529B"
```

## Python

[ord()](https://docs.python.org/ja/3.13/library/functions.html#ord) とフォーマット指定子つきの [f-strings](https://docs.python.org/ja/3.8/tutorial/inputoutput.html#tut-f-strings) を使います。 

```shell-session
$ python --version
Python 3.13.0
```

```py
>>> char = 'カ'
>>> f'U+{ord(char):04X}'
'U+30AB'

>>> char = '力'
>>> f'U+{ord(char):04X}'
'U+529B'
```

## 解説

どちらの場合でも文字を `04X` という形式でフォーマットしています。

- `04`: 4 桁を 0 埋め (例: '12' → '0012')
- `X`: 大文字の 16 進数表記 (`x` だと小文字)
文字列をコピーして遊ぶ。(舐めると火傷するぜ!!)(わかるかな?)(ほぼオリジナル)


目的
文字列のコピーする
特に説明なし

いろいろ
そう言う、態度が気に入らないのよ!!(三年目の浮気　歌)(インターネット老人会?)
真面目にしさしぶりにデバッグしたよ。ーーーー(20年ぶり以上)
なぜかアフターとビターが逆、直すのめんどいからいいか


オンラインコンパイラ


```c++

#include <iostream>
using namespace std;
int main(void){
    // Your code here!
    
    //char *s;         //サーチ
    char *c = "Bomb";  //チェンジ
    //char *a;         //全体
    char b[16] = {0};  //一時領域
    
    printf("after\n");
    printf("[%s]\n",c);
    printf("(%s)\n",b);
    
    int i = 0;
    while( (b[i] = c[i]) ){i++;}

    printf("before\n");
    printf("[%s]\n",c);
    printf("(%s)\n",b);

}

```


```

after
[Bomb]
()
before
[Bomb]
(Bomb)

```
Linuxサーバの遠隔停電対応

# はじめに
大学の計画停電があるとのことで，その対応をする必要があったのですが，片道1時間半の研究室まで電源の対応のために通学するのは億劫ということで，何とかできないかと探した次第です．

要件としては，

- 連休中で特に研究室に行く用事がないため，遠隔で済ませたい
    - BIOSの操作が不要
- 計画停電以外ではできる限り，サーバが利用できない状況を避けたい
    - 指定時間に起動する

というものです．


# 実行方法
軽く調べてみたところ，BIOSの設定を使うもの，`cron`コマンドを使うものなど，様々な方法がありましたが，上述の条件で個人的には`at`コマンドと`rtcwake`コマンドを使う方法が合いました．

```bash: 
~# at -t "202412011200"    # 2024年12月1日 12時00分に実行
at Sun Dec 1 12:00:00 2024
at> rtcwake -m off -s 86400
ctrl+D
at> <EOT>
job 1 at Sun Dec 1 12:00:00 2024
```

`at`コマンドは後でコマンドを実行するコマンド[^1]です．（コマンド多すぎ）
`-t`オプションを付けることで時刻を指定することができます．
実行するコマンドの入力を求められるので，`at>`に続いてコマンドを入力します．最後まで入力できたら，`ctrl + D`を入力することで決定されます．

[^1]: https://www.ibm.com/docs/ja/aix/7.3?topic=command

次に，`rtcwake`コマンドです．[^2]

[^2]: https://man7.org/linux/man-pages/man8/rtcwake.8.html

`-m`オプションでモードを選択できます．今回の`off`はPoweroff，すなわち電源が落ちます．`-s`で起動までの時間（1日 = 86400秒）を指定できます．

最後に，設定の確認は`atq`と入力することで一覧が表示されます．


# 最後に
もう少しうまくやる方法がある気もしますが，それほど複雑でなく，かつ，複数のコマンドを指定時刻に実行する`at`コマンドを知ることができたということで良しとしたいと思います．
SaaSに頼らない自前でE2Eテストの構築と運用

## 1. はじめに
E2Eテスト（エンド・ツー・エンドテスト）は、アプリケーションの動作が期待通りかを確認するために重要なテスト手法です。多くの企業がSaaS型テストツールを使用していますが、自前でE2Eテスト環境を構築し運用する方法もあります。
本記事では、SaaSに頼らず自前でE2Eテストを行うための基本的な構築方法、メリット・デメリット、運用のポイントについて解説します。
## 2. 自前でE2Eテストを行うための準備
ここでは、どのようなツールを使うか、またどういった環境を準備するかを紹介します。

### 2.1 テストフレームワークの選定
- CodeceptJS: 使いやすく、さまざまなテストをサポートするフレームワーク。非同期のテストも簡単に書ける
- Playwright: 複数のブラウザに対応し、並列実行をサポート。高いパフォーマンスを持つ
- Cypress: フロントエンドのテストに特化し、リアルタイムでブラウザの状態を確認しながらテストを行える
### 2.2 テスト環境の自動構築
Dockerを使って、テスト環境をコンテナ化する方法を解説。CI/CDでの自動化を進めることも重要です。例えば、Docker Composeを使って、複数のコンテナを連携させる方法を紹介します。
### 2.3 並列実行の設定
並列テストを活用することで、テストの実行時間を大幅に短縮できます。PlaywrightやCodeceptJSなどのフレームワークを使って並列実行を行う設定方法を説明します。

## 3. メリットとデメリット
自前でE2Eテストを行う場合のメリットとデメリットを整理し、読者が選択を考えるための助けとなるように記載します。

### 3.1 メリット


1. **高度なカスタマイズが可能**
   - テストの条件や環境を詳細にカスタマイズできます。たとえば、特定のネットワーク制約やデータ構成、ブラウザ設定を自由に設定可能で、プロジェクトに最適なテスト環境を整備できます。
2. **コスト管理の自由度が高い**
   - 長期的にはSaaS利用のサブスクリプション費用を削減でき、自社サーバーやオンプレミスでの実行によりコスト管理がしやすくなります。特に大規模なテスト環境では、コストの大幅削減が可能です。
3. **セキュリティ・コンプライアンスの強化**
   - SaaSを使用するとデータが外部に出るリスクがありますが、自社環境であればデータの流出リスクを防げます。機密データの保護や社内ポリシーに適したセキュアなテスト運用が可能です。
4. **運用ノウハウの蓄積**
   - テストフレームワークやCI/CD構築における技術力が社内に蓄積されます。問題解決や新機能の実装も社内で対応可能になるため、運用チームのスキル向上や自己完結型の技術力が身につきます。
5. **テスト実行のスピード向上**
   - 自社内のリソースに合わせて最適な設定ができるため、インフラを工夫すればSaaSよりも高速にテストが実行できる場合もあります。負荷テストや高頻度のE2Eテストも迅速に行えます。
6. **既存の技術資産をフル活用可能**
   - 社内で既に使っているツールやインフラをE2Eテストに統合しやすく、システム全体を最大限に活用できます。既存リソースに依存することで、新たなシステムの導入コストも低減できます。
7. **独自のテスト環境が容易に再現可能**
   - Dockerや仮想環境を使えば、テスト環境を簡単に複製・再現できます。開発環境とテスト環境の整合性を確保しやすく、デバッグや問題追跡も効率化されます。
8. **長期的なリスク軽減**
   - SaaSプロバイダーのサービス終了や価格変更に左右されず、継続的かつ安定した環境でテストを実行できます。自社の運用ポリシーに合わせた長期的な安定性を確保できます。
9. **カスタムレポート作成の自由**
   - テスト結果の出力形式やレポートのカスタマイズが自由にできます。Allureなどのレポート生成ツールと連携させることで、より詳細で見やすいレポートを出力可能です。
### 3.2 デメリット
1. **初期構築の手間**
    - 環境をゼロから作り上げるため、時間とリソースがかかる
2. **メンテナンスの負担**
    - システムのアップデートやトラブルシューティングが必要
3. **スケーラビリティの課題**
    - テスト規模が大きくなると、リソースの確保や管理が大変
4. **トラブルシューティングの難易度**
    -  問題解決には高度な知識や対応が必要になる場合がある

## 4. 実践: 自前でE2Eテストを実行する

### CodeceptJSのセットアップ手順

#### 1. プロジェクト作成とCodeceptJSインストール
```bash
mkdir codeceptjs-sample
cd codeceptjs-sample
npm init -y
npm install codeceptjs puppeteer --save-dev
```
#### 2.初期設定
```bash
    npx codeceptjs init
```
- テストディレクトリ: ./tests
- ブラウザ: Puppeteer
- URL: https://example.com
#### 3. テスト作成
`tests/example_test.js` に以下を追加：
```javascript
Feature('Example Test');
Scenario('check Example.com title', ({ I }) => {
  I.amOnPage('/');
  I.see('Example Domain');
});
```
#### テスト実行

```bash
npx codeceptjs run --steps
```
- Playwrightでの並列テスト実行: 複数ブラウザでのテスト実行方法。
- Docker環境の構築: テスト用コンテナのセットアップとDocker Composeの設定例。
## 5. 運用のポイントと改善点
E2Eテストを運用していく中での注意点や改善方法を紹介します。

- テストの保守性を高める: 定期的なコードレビューやリファクタリングを実施し、テストコードの保守性を高める方法。
- CI/CDパイプラインへの統合: 自動化したテストをCI/CD環境に組み込んで、継続的にテストを実行する方法。
## 6. まとめ
自前でE2Eテスト環境を構築することには多くのメリットがある一方で、運用に関する負担や初期設定の手間も存在します。自社の状況に応じて、どの方法が最適かを検討し、最終的に高効率なテスト運用を目指しましょう。

## 参考
- CodeceptJS公式サイト: https://codecept.io/
- Playwright公式サイト: https://playwright.dev/
- Cypress公式サイト: https://www.cypress.io/
【C言語】ファイル分割

## ファイル分割(C、C++)
### メリット
1. 複数のプロジェクト（プログラム）間での関数・クラスの再利用を簡易化
1. コンパイル時間の短縮化
1. ソースファイルの可変性を高める
### デメリット
1. グローバル変数の受け渡し
1. 多重インクルード(ヘッダーでヘッダーの読み込みを避けること推奨)
1. ソースの量の増加

```C:example_before.c
#include <stdio.h>

// この関数があることを周知させる
// (関数のプロトタイプ宣言)
void PrintfHelloWorld(void);

int main(void)
{
	// 実行(関数の呼び出し)
	PrintfHelloWorld();

	return 0;
}

/// <summary>
/// Hello Worldを出力する
/// (関数の定義)
/// </summary>
void PrintfHelloWorld(void)
{
	printf("Hello World");
}
```
```C:example_after.h
#ifndef EXAMPLE_H_INCLUDED // インクルードガード
#define EXAMPLE_H_INCLUDED // インクルードガード

// この関数があることを、
// ヘッダーを読み込んだcファイルに周知させる
void PrintfHelloWorld(void);

#endif // !EXAMPLE_H_INCLUDED(インクルードガード)
```
※#ifndef、#define、#endif
ヘッダーを多重に読み込まないようにする(**インクルードガード**)

```C:example_after_sub.c
#include "example_after.h"
#include <stdio.h>

/// <summary>
/// Hello Worldを出力する
/// (関数の定義)
/// </summary>
void PrintfHelloWorld(void)
{
	printf("Hello World");
}
```

```C:example_after_main.c
#include "example_after.h"

int main()
{
	// 実行(関数の呼び出し)
	PrintfHelloWorld();

	return 0;
}
```

## 関数のオーバーロード
**用途 : より再利用できるようにするため、引数の対応幅を広げる**

```C
int Add(int a, int b) { return a + b }
float Add(float a, float b) { return a + b }
```

## インライン関数(簡単に説明できない、スマン)
処理が少なく、呼び出し回数が多い関数は
(※)関数呼び出しのオーバーヘッド がもったいないので...
**用途 : 関数呼び出しのオーバーヘッドを削減する**

**inline**とは関数呼び出しの箇所に関数本体のコードを直接埋め込むことを
コンパイラに指示する機能

- (※)**関数呼び出しのオーバーヘッド**
1. 実行中のプログラムから、呼び出したい関数の最初の命令へジャンプ(関数へのジャンプ)
1. 関数に渡す値（引数）を、関数内で使えるようにメモリ上に配置(引数の受け渡し)
1. 関数の終了後、元のプログラムに戻ってくるためのアドレスを記憶(戻りアドレスの保存)
1. 関数内の処理を実行(関数の実行)
1. 関数が計算した結果（戻り値）を、呼び出した元の場所へ(戻り値の受け取り)
1. 関数が終了した後、記憶しておいた戻りアドレスへジャンプして、
元のプログラムの実行に戻る。

```C
// 従来の関数
int PlusOne(int num)
{
    return num + 1;
}

// インライン関数
inline int PlusOne(int num)
{
    return num + 1;
}
```
※inlineを付けた関数は定義しなければならない

## 名前空間(C++、C#)
**用途 : 同名の命名がなされているものを区別する**

### C++
```C++
namespace
{
    宣言・定義
}
```

```C++:example.cpp
#include <iostream>

namespace One
{
    inline void PrintfHelloWorld(void)
    {
        std::cout << "Hello World 1" << std::endl;
    }
}

namespace Two
{
    inline void PrintfHelloWorld(void)
    {
        std::cout << "Hello World 2" << std::endl;
    }
}

int main(void)
{
    One::PrintfHelloWorld();
    Two::PrintfHelloWorld();

    return 0;
}
```

### C#
```C#:example.cs
using System;

namespace One
{
    public class Sample
    {
        public static void PrintfHelloWorld()
        {
            Console.WriteLine("Hello World");
        }
    }
}

namespace Two
{
    public class Sample
    {
        public static void PrintfHelloWorld()
        {
            Console.WriteLine("Hello World2");
        }
    }
}

class Program
{
    static void Main()
    {
        One.Sample.PrintfHelloWorld();
        Two.Sample.PrintfHelloWorld();
    }
}
```
コンポーネントのkeyにarray index は使わない

最近知って残しておきたいことのメモです。

#### 💡react component のkey にarray index は使用しない

先輩のアドバイスの表現をお借りすると...
```plaintext
配列のindexをコンポーネントの key に指定すると、
それは本質的に一意な値ではないため
配列の変更に伴って不要な再レンダリングが発生するなど非効率
⇒ 避けるべき実装である
```
（参考）https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-array-index-key.md

#### これを聞いてどうにか頭を整理した結果↓
- Reactの仮想DOMの差分でレンダリングする特性に関連している
- 配列のindexは、例えばある要素が削除されたり先頭に追加されると、他の要素のindexにも変化が起こる（各要素のindexがひとつ前にずれたり後ろにずれたり）
--->>> 上記の2点から、本来は同じ要素なのに、前回のレンダリングからindexが変わっていると、違う要素だとReact側が認識し、不要なレンダリングが行われたりパフォーマンスが低下しうる。

#### 以下、eslint-plugin-reactのgithubから拝借
```typescript
// よくない例
things.map((thing, index) => (
  React.cloneElement(thing, { key: index })
));
```
```typescript
// よい例
things.map((thing) => (
  React.cloneElement(thing, { key: thing.id })
));
```

これに則って実装をしようとしたとき、シンプルな文字列の配列とかだとindexしかkeyに指定できるものない....とも思ったりしたのですが、それなら指定できる一意になるプロパティを追加しちゃえばいいのかな？と思い、文字列の配列をオブジェクトの配列に変形させたりしてみました。
```typescript
// 元の配列と処理
const prefectures = ['東京', '埼玉', '千葉', '神奈川']

prefectures.map((prefecture, index) => (
  React.cloneElement(prefecture, { key: index })
));
```
↓
```typescript
// 修正した配列と処理
const prefectures = [
  { id: 1, name: '東京' },
  { id: 2, name: '埼玉' },
  { id: 3, name: '千葉' },
  { id: 4, name: '神奈川' }
]

prefectures.map((prefecture) => (
  React.cloneElement(prefecture, { key: prefecture.id })
));
```

#### ESLintのルールで、keyにindexを渡すことを検出するには↓
```typescript
 // 省略
 "rules": {
    "react/no-array-index-key": "warn" // または"error"
  }
```

最近は「処理効率の良いコード」に興味。
どうやってそれの学びを深めるのかもよくわからないですが
こうやってひとつひとつ吸収していけたらと思っています。

**🙏最後に🙏**
初学者のメモレベルですが、もし誤認があったり誤解を与えるような表現がありましたら、お手数ですがご指摘をいただけますと幸いです。
Ubiquiti UCGのSite to Site VPNについて．

## やりたいこと
- 複数拠点でVPNを相互接続したい．
- 環境はUbiquitiの各種Router．
- 今回はUGCとUDMSE．

## 現状
- Site Magic
    - Pros
        - WireGuardとOSPFを組み合わせたメッシュネットワーク型のSD-WANを構築．
    - Cons
        - どうやらうまく動かないらしい．：[Link](https://community.ui.com/questions/Site-Magic-Group-connected-but-not-working/7589b310-481e-49f8-b602-704a97829b12)
        - 各拠点間のオーナーが同じ必要がある．
- Site to Site VPN
    - Pros
        - 複数拠点間でオーナーが違くても良い．
        - マルチベンダー対応可能
        - セキュリティ面でのカスタマイズ性
    - Cons
        - 二つの設定をバラバラにしなければならない．管理コスト
        - 1対1の接続
        - Hub-and-Spoke型になるとボトルネックが生まれる．

今回は今のFirmwareでSite Magicが動かないらしいのでSite to Site VPNを採用．

## 設定
### 今回の環境について
オレンジ色で囲んだRaspi同士で接続したい．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3291593/5ec175c6-7b55-4f13-8051-4a1d258679f8.png)

### 今回の設定
- 一般
    - VPNタイプ：IPSec
    - 名前：任意のもの
    - 事前共有キー：どちらかのキーを接続先のVPN設定にも入力（接続端末同士で同じにする）
    - リモートIP：お互いの接続先のIPを入力
- ネットワーク構成
    - VPNタイプ：ルートベース
    - トンネルIP：使用せず
    - リモートネットワーク：接続したい端末のいるネットワークを入力（192.168.6.0/24など）

設定画面のスクショ
![スクリーンショット 2024-11-09 18.41.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3291593/6eb91928-3299-9f65-58cd-da357ce7f8e5.png)

## 落とし穴
- お互いの`ネットワーク構成/リモートネットワーク`に設定しているサブネット以外の通信はできない．そこで，端末のVLAN設定などをミスると接続できない．ローカルの同一ネットワーク内（今回は192.168.2.0/42)に接続できることを確認してみてください．
アクセシビリティに必要なものとは

# はじめに []()
HTML解体新書にてアクセシビリティを考慮した開発が必要であると知った。
そして実際にどのような考慮が行われているのか気になった。そこで現在公開されているいくつかのWebサイトを対象に、Tabキーのみで閲覧し、アクセシビリティの具体的な実装内容を確認した。

# 調査したサイト []()
- Qiita
- Zenn
- MDN
- Youtube
- その他数社のホームページ

# アクセシビリティに必要な実装 []()
調査の結果、Tabキーのみでもマウスと遜色なく閲覧できるサイトでは以下のことが実装されていた
1. メインコンテンツへのスキップリンク
1. マウス操作時と同様の画面変化
1. 見出し・小見出しへのフォーカス

## 1.メインコンテンツへのスキップリンク []()
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508744/96adaad1-5750-3f65-47d4-b31a2d58710f.png)
同ページのメインコンテンツへフォーカスを移すためのリンク
YoutubeやMDNといったナビゲーションや検索フォームなどメインコンテンツ以外のコンテンツが多いサイトで確認できた。
### メリット
一回で閲覧したい箇所までフォーカスを移動できる。
### ない場合のデメリット
このリンクがない場合、別ページに遷移するたびにメインコンテンツまでフォーカスを合わせる必要がある。遷移するたびにTabキーを何回もクリックする必要があり、閲覧に労力を使う。スキップリンクがないサイトを閲覧した際、私は二度とそのサイトへアクセスしないと考える人がいてもおかしくないと思った。


## 2.マウス操作時と同様の画面変化 []()
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508744/59a7c1d5-454d-7e25-b520-b8d44dfbe287.png)
マウス操作と同様に画面が変化する実装。
MDNが非常に良い実装だと感じた

### メリット
フォーカスしている場所が把握できる

### ない場合のデメリット
フォーカスしている場所が把握できず閲覧しにくい
主にCSSのhoverとforcusについてである。多くのサイトでマウスカーソルがコンテンツ上に乗った時(hover時)にその状態が変化する。しかし、Tabキーによる選択はhoverでなくforcusである。そのため、hoverだけで変化する実装の場合Tabキー操作ではコンテンツの状態が変化せず、現在フォーカスしている場所を見失う
***特に***、上画像のようなリストが隠れている時が非常に厄介だった。突如フォーカスが消失し何回Tabキーを押しても現れないという事象が発生する。そして、フォーカスが予想外の場所に出現し、もう一度1から閲覧する必要が出てくる。

## 3.見出し・小見出しへのフォーカス []()
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508744/4a2ef3ec-1966-48e8-7e6a-35c058a5a4cb.png)
MDNとZennで確認できた実装
h1~6はデフォルトではTabキー操作でフォーカスされない。子要素に`href`属性をもつ`<a>`タグを持たせることで、Tabキー操作でフォーカスされるようにする。`<a>`タグの向き先は親要素のid
```html
<h2 id="見出しID">
    <a href="#見出しID">フォーカスされる見出し</a>
</h2>
```

### メリット
閲覧場所が把握しやすい
Tabキーを押すことで各見出しにジャンプしフォーカスが表示される。閲覧したいコンテンツがページ最下層に記載されていてもTabキーのみで移動ができる。また、見出しにフォーカスが当たるため現在閲覧しているコンテンツを把握しやすい

### ない場合のデメリット
サイトの閲覧に十字キーが必要になる。
上2つと比べて影響度は小さく、なくても殆ど気にならなかった。だが、あった場合はTabキーのみで閲覧でき非常に便利だった。

# あとがき
アクセシビリティに必要な実装として以下の3つを上げた
1. メインコンテンツへのスキップリンク
1. マウス操作時と同様の画面変化
1. 見出し・小見出しへのフォーカス

この中でスキップリンクと画面変化は閲覧時のストレスの観点から必須だと感じた

最期にこの調査を経てアクセシビリティを考慮したサイトと考慮していないサイトの模型を作ってみたため、ここに記載。
※0.5x推奨
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="bGXQKMp" data-pen-title="アクセシビリティを考慮したサイト" data-user="Momokonomi" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/Momokonomi/pen/bGXQKMp">
  アクセシビリティを考慮したサイト</a> by Momokonomi (<a href="https://codepen.io/Momokonomi">@Momokonomi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
SORACOM Flux と LINE Messaging API の連携方法！LINE公式アカウントとの連携も可能に！

# はじめに
この記事では、SORACOM Flux と LINE Messaging API の連携方法を解説します。
SORACOM Fluxのアクションには、「LINE通知」が用意されているのですが、現在は、LINE Notifyを使った仕組みであり、「今後サービスの終了がアナウンスされている」「LINE公式アカウントなどとの連携も考えたい」ということで、今回は LINE Messaging API との連携方法を解説します。

# 具体例
LINE公式アカウントで、ソラカメで取得した画像を、AIアクションで分析した文章を配信しています。このような形で、LINE公式アカウントで配信することが可能となります。
<br>

![Image (4).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21408/903abfd4-888d-2f52-b6e2-e900346a1eef.jpeg)


<br>
今回の例では、SORACOM Harvest Filesにアップされた画像を、AIアクションを使って画像解析して、その解析した結果をLINE公式アカウントで配信するというシステムを例に説明します。全体のフローは以下のような感じとなり、LINE公式アカウントにメッセージを送るために、Webhookアクションで、LINE Messaging APIを使って、メッセージを送信します。
<br>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21408/a92861f3-de6d-dc1d-26f2-93e52f0060c9.png)

# 連携方法

LINE公式アカウントの作成やアクセストークンの発行などは、別途事前に行って下さい。
今回は、SORACOM Flux 上で連携する方法にフォーカスして解説します。

#### 新しいアクションを作成

LINE Messaging API を使用して、LINE公式アカウントでメッセージを配信します。そのため、アクションとしては、「LINE通知」ではなく、「Webhook」を使用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21408/061d0268-c266-5b69-301c-829ce7e6ae61.png)

#### アクション内容を記載

LINE Messaging API を使用するので、HTTPメソッドを使用します。デフォルトの[CONFIG]設定は以下のようになっています。こちらを編集して、LINE Messaging API と連携させます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21408/c254a654-e5c4-07b3-5182-f23c189ba72a.png)

参考例は以下のとおりです。それでは、詳細の内容を確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21408/c9540f16-71a7-1784-2716-88198c05cfa0.png)

それぞれの設定内容は以下のとおりです。

* HTTPメソッド：POST
* URL： https://api.line.me/v2/bot/message/broadcast 　※この例はブロードキャストしています
* HTTPヘッダー：
    * content-type：application/json
    * Authorization：Bearer {channel access token}
* HTTPボディ
```json
{
    "messages":[
        {
            "type":"text",
            "text":"Hello, world1"
        }
    ]
}
```

また、SORACOM Fluxでは、
『${payload.temperature} のようなテンプレート表記を使って動的に値を構築することが可能です』
とあるので、AIアクションを使った結果を活用したい場合などは、HTTPボディの中に以下のように記述することで、前のアクションの結果を使って動的にメッセージを変更することができました。

```json
{
    "messages":[
        {
            "type":"text",
            "text":"${payload.output.description}"
        }
    ]
}
```

以上で、SORACOM Flux と LINE Messaging API の連携が可能となります。

# 最後に
Webhookアクションが使えるということで、比較的容易に LINE Messaging API と連携して、LINE公式アカウントにメッセージを送信することができました。Webhookに対応しているサービスとの連携はある程度、この方法でやれるような気がしています。


# その他の参考リンク

https://qiita.com/yukima77/items/e2b78d506575d82d9bce

https://qiita.com/yukima77/items/7b65d0695f06ec074343

https://qiita.com/yukima77/items/cb6032987d60ee35a2bd
文字列の長さを求める


x 過去ログをみよ
x c++といいながら、なぜかc言語

目的
ながさを測って遊ぶ

オンライコンパイラ


```c++

#include <stdio.h>
int main(void){
    // Your code here!
    
    char *s = "Alice";
    //char *c; //チェンジ
    //char *a; //全体
    printf("%s\n",s);
    
    int i = 0;
    while(s[i++]){/*空文*/}
    printf("%i\n",(i-1));
    
}



```

```


Alice
5


```
podmanのcontainerをsystemctlで自動起動させる備忘録

(1) systemctlのunit-fileを生成

生成する先のパスが重要

```bash
podman generate systemd --name n8n-app > ~/.config/systemd/user/n8n-app.systemd.service
```

(2) daemonを再起動(`--user`が重要)

```bash
systemd --user daemon-reload
```

(3) systemctlから認識されているかを確認

```bash
systemctl --user list-unit-files
```

(4) 起動／ステータス確認／停止をやってみる 

```bash
systemctl --user start container-n8n-app.service
systemctl --user status container-n8n-app.service
systemctl --user stop container-n8n-app.service
```

(5) 問題なければenable

```bash
systemctl --user enable container-n8n-app.service
```

参考: https://www.zu-min.com/archives/875
現場で使ったLinuxコマンド備忘録：2年目編

## はじめに
はじめまして、株式会社エニプラの野口です。
インフラ系の業務に携わって2年目になります。
去年には下記の記事を投稿しており、現場にて活用したコマンドについて書いておりました。

https://qiita.com/NoguchiHikaru/items/48a93d876dbb17f7706c

投稿してから1年の月日が経ちまして、今までの振り返りを込めて現場で利用したコマンドを
書いていこうと思います。

## ・vi
Linux上におけるテキストエディタに当たるコマンドです。

主に「hosts」「crontab」「passwd」ファイルで仕様変更があった際に使用しております。
普段はローカル環境のサクラエディタ等で予めファイルを作成してからWinSCPで、
Linux環境へ転送して上書きをするのですが、微々たる修正であれば `vi` コマンドで済まします。

## ・view
読み取り専用でファイル閲覧するコマンドです。

主にシェルの構造を把握するために使用しております。
現場で使用されているシェルの大半が引き継がれた物なので、
使用前も当然ですが、エラー発生時の原因解析でも理解するうえで活用しております。

catコマンドとの違いとしましては、
フルスクリーンで表示されるのとサブコマンドによるテキスト検索(　/〈検索対象〉)が可能なところです。

## ・ssh ユーザ名@ IPアドレスまたはホスト名
各サーバ間での疎通確認でpingコマンドとセットで使用しております。
ネットワークチームが開通した後に実施するのが主な用途です。

## ・hostname ; date
ホスト名とコマンド実行時の日時を出力するコマンドになります。
Linux上での試験での証跡取得で使うコマンドです。
現場によっては実施日の記載がないといけないところもあるので作業前に使って、損はないです。

## ・history
過去に実行されたコマンドを表示させるコマンドになります。
作業引き継ぎでコマンドの所在が分からないときやエラー発生時の原因調査で使用しました。
sqlplusコマンドにてパスワードをセットに実行してもそれごと記録されるので、気を付けましょう。

## 最後に
以上が現場で使ったLinuxコマンドになります。
他にもJP1やHULFTといった製品由来のコマンドを使用したりもしてますが、
ピンポイントなところが多いので今回は割愛いたします。

AWSコマンドとシェルも使用しており、こちらは次回に書いてみたいと思っております。
MacにDjangoの動作環境を構築

# やりたいこと
- Mac に Python 及び Django のフレームワークをインストール
- Django のプロジェクトを作成
- 作成したプロジェクトをローカル環境で動作

# 前提
- OS
    - macOS Sonoma 14.6
- 各バージョン
    - homebrew 4.4.4
    - pyenv 2.4.17
    - pip 24.3.1
    - python 3.12
    - Django 5.1.3

# pyenv のインストール
python をバージョンごとで管理したかったため、以下のコマンドを実行して pyenv をインストール
```bash
brew instal pyenv
```

# Python のインストール
以下のコマンドを実行
```bash
pyenv install 3.12
```
インストールした Python のバージョンを適用
```bash
pyenv global 3.12
```

適用されているか確認
```bash
% python3 -V
Python 3.12.7
```

# pip のインストール
[公式ドキュメント](https://pip.pypa.io/en/stable/installation/)のインストール方法に則り、以下の`curl`コマンドを実行
```bash
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
```
その後以下のコマンドを実行し`get-api.py`をインストール
```bash
python3 get-apt.py
```
実行結果の最後に`Successfully installed pip-{バージョン}`と表示されればOK


### Warningが出力された場合
実行結果の途中で以下のような`Warngin`が出力される場合もある
```bash
WARNING: The scripts pip, pip3 and pip3.9 are installed in '/Users/username/Library/Python/3.9/bin' which is not on PATH.
```
これはインストールした pip が PATH が通っていないため、以下の記事を参考に PATH を通せばOK
[MacでPATHを通す](https://qiita.com/nbkn/items/01a11392921119fa0153)

# Django のインストール
以下のコマンドを実行して Django をインストール
```bash
pip install django
```
実行結果の最後に`Successfully installed django-5.1.3`と出力されればOK

# プロジェクトを作成
今回は日記アプリを作成する想定の元、`PythonDiary`というプロジェクト名で作成
プロジェクトを作成したいディレクトリに移動し、以下のコマンドを実行
```bash
cd app
django-admin startproject PythonDiary
```

# ディレクトリ構成
```
PythonDiary
  ├── PythonDiary
  │   ├── __pycache__
  │   │    ├── __init__.cpython-312.pyc
  │   │    ├── settings.cpython-312.pyc
  │   │    ├── urls.cpython-312.pyc
  │   │    └── wsgi.cpython-312.pyc
  │   ├── __init__.py
  │   ├── asgi.py
  │   ├── settings.py
  │   ├── urls.py
  │   ├── wsgi.py
  └── manage.py
```

# ローカルサーバーを起動
以下のコマンドを実行
```bash
python manage.py runserver
```
実行結果の最後にローカル環境の URL が出力される
```bash
% python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
November 09, 2024 - 08:50:11
Django version 5.1.3, using settings 'PythonDiary.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
```
→ http://127.0.0.1:8000/ へアクセスすると Django のトップページが表示される
![django_top.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3123079/c9f31665-6c6c-2065-f3c5-bf423ad4befe.png)
"専任不在"の会社で奮闘する、情シス業務委託エンジニアの心得

# はじめに
巷では、「仕事の進め方」に関するノウハウはたくさんあるので、その中でも「情シス専任がいない会社で、情シス担当者として業務委託で働くとき」に私が気をつけている点をまとめました。

したがって、本投稿は**情シス専任の責任者がいない会社で、業務委託として情シスをしている人**を想定読者としています。

:::note info
表現に関する補足）本投稿においては、以下の通りで表現しています。
- お客様：業務委託として参画している先の法人、会社そのもの
- 担当者：お客様の中で情シスの業務をしていて、業務で普段関わっている方
:::


## 3行にまとめると

- 業務委託を呼んでる会社は忙しい
- 忙しい人の負担にならないコミュニケーションを取ろう
- お客様の会社・担当者の様子に敏感になろう

# 本題に入る前に、そもそも業務委託を呼ぶ会社はどういう状況なのか？

気をつけていることを書く前に、そもそも情シス担当者を外部から呼ぶ会社はどういう状態なのかを整理しました。経験上、多くの場合は

- 入社にともなうアカウント発行やPCセットアップ、日々の問い合わせ業務が増えてきて、捌ききれない。さらにセキュリティを強化していきたいが現状維持で手一杯
- だからと言って、手順書を整理して派遣社員やアルバイトに業務を切り出す余裕もない
- そのうえ、本当は正社員を雇いたいけれど、どんな人がいいのかも分からなかったり、面接をしてもピンとくる人が応募してくれない

という状況です。

そんな状況で呼ばれた我々は、少しでも上記課題が解消できるように動く必要があるわけですが、具体的に何を気をつけるべきなのか？

任されたプロジェクトや業務を責任を持って進めることは前提として、わたしが日々気をつけていることを整理しました。


# コミュニケーション編

### 投げ返しやすいようにボールを投げる

「そもそも業務委託を呼ぶ会社はどういう状況なのか」で記載した通りで、そもそも担当者には情シス業務とは別に主務があります。その業務のかたわら情シスに関わる業務を対応・判断しているわけです。

そのため、その担当者の主務の邪魔をしないように、1秒でも主務に集中できるように我々は行動すべきと考えています。そのためには具体的には以下の2点を意識しています。

#### ①依頼事項があるときは、相手への要望・期日を明確にする

遠慮して行間を読んでもらおうとするのは、忙しい人を相手にしている我々にとっては悪手です。意味のわからない依頼は後回しにされやすいですし、考える時間を与えてしまい負荷になってしまうからです。

依頼を投げる前に、改めて何をして欲しいのか、いつまでに対応して欲しいのかを整理した上で依頼をするように心がけています。

#### ②相談事項があるときは、判断できるだけの材料を全て集め整理する

何か判断して欲しいことがあるときは、「もし自分が判断するならどんな情報が欲しいのか？」という視点で情報収集・整理したうえで相談するようにしています。

細かいすり合わせが必要そうな場合は、テキストコミュニケーションではなく議論できる時間を別途準備し、その時間内で結論を出せるようにします。

テキストコミュニケーションは、非同期であるがゆえに「話を思い出す」という作業が生まれがちです。まとめて時間をとって同じ情報量にしてその場で結論を出せるようにすることで、お互いの負担を減らせます。

### 相手の理解度・立場に合わせた説明をする

担当者は情シス専任ではないため、ITにあまり詳しくない場合が多いです。そんな担当者とコミュニケーションをとるうえできをつけている点として2つあります。

#### ①相手の頭の中でイメージ図を描けるように話す

目に見える事象であればその場で見せながら説明すれば良いですが、目に見えない部分の話や未来の話をする場合は、なかなか相手に伝わらないことがあるかと思います。そんなときは、イメージ図を相手に描かせるように話しています。例えば

- ネットワークの話をするときは、道路や家、住所などに例える
- PCの話をするときは、体の構造に例える

などです。なお、抽象度が高く口頭で示せない場合は、実際にイメージ図を書いたり、実際に体感してもらうようにしましょう。

#### ②相手のための資料を準備する

お客様に提案する際には、「自分が提案したあとは、誰がどういう方法で検討・判断するのか」を理解したうえで説明しましょう。

決済者は別にいて、その部下にあたる担当者に対してまず説明したいとき、以下に気をつけて情報を整理しています。

- 担当者が気になるであろう細かい情報はプレゼン資料とは別にする
- 担当者が上司に説明するときや稟議を進める際に使いやすいフォーマットにする
- 資料を後から見返した時もわかるように、口頭補足にたよらずあえて文字に残す
- 社内で使われている言葉に合わせる
- 社内でよく出る比較対象の情報は網羅する

言葉を使う以上、その定義は厳密にすべきではありますが、社内で独特な使われ方をしていたり、社内特有の言葉があれば、積極的にそのいい回しを採用しています。

# スタンス編

### お客様の情報に敏感になる

自身のポジション・役割にもよりますが、業務委託である以上はどうしても正社員よりも社内の情報が少なくなりやすいです。

中長期の経営方針、短期的な経営成績、社員のプロフィールなど、正社員であれば社員総会や日々の業務の中で触れられる情報も、業務委託となるとアクセスできなかったり、能動的に取りに行く必要があります。

事前に会社情報を調べたり、アラート機能を使ってプレスリリースを把握するだけでなく、お客様先で働いているからこそ得られる情報もあると考え、具体的には日々以下のことを意識しています。

- お客様先の社員さんの表情、部署の雰囲気（慌ただしい様子か、和やかな雰囲気なのかなど）を観察する
- 業務で深く関わる担当者やその上司のスケジュールを覗いてみる
- 移動中や休憩中、担当者が所属する部門宛にくる依頼・相談の内容を観察する

### 担当者・お客様の優先度を把握する
日々、各方面から依頼や問い合わせを受けていると、業務の優先度を見失ってしまうことがあるかと思います。そんなときは、我々を評価してお金を払うのは誰なのか、そしてその人は何を優先しているのかを思い出すようにしています。

なぜなら、どれだけいい仕事をしたとしても、評価する側の意図・優先度と異なっていれば、お金を払う側からすると無駄なコストでしかないからです。

もし、把握している優先度とは異なる角度から差し込みの業務が来たときは、優先度を担当者とすり合わせつつ、追加対応のために時間を使うことを合意するようにしています。

# おわりに

うまく言語化・構造化ができず、いくつか本投稿に含んでいない点もありますが、概ね網羅できているのではないでしょうか。

本投稿を通じていろんな出来事を思い出し、「お客様があっての我々である」ということを意識して、今後も業務に取り組んでいこうと改めて思えました。
【Rails】N + 1問題についてそろそろちゃんと向き合わなきゃな...

# 「あー、N+1問題ね。うんうん...もちろん考慮すべきだね」
と言いつつ朧げな理解のままここまで生きてきました。
歴が長くなるにつれこういう基本的なことを知らないのがバレると恥ずかしいので
恥をかく前にちゃんと理解しておこう。

## eager_load

指定したassociationをLEFT OUTER JOINでキャッシュする

```
orders.eager_load(:order_items)
```
```
SELECT
	`orders`.`id` AS t0_r0,
	`orders`.`store_account_id` AS t0_r1
FROM
	`orders`
	LEFT OUTER JOIN `order_items` ON `order_items`.`order_id` = `orders`.`id`;
```
## preload

ordersテーブルからデータを取得
取得してきた`order`のidを持つ`order_items`をIN句で取得
クエリが2回実行される
```
orders.pre_load(:order_items)
```
```
SELECT `orders`.* FROM `orders`;

SELECT
	`order_items`.*
FROM
	`order_items`
WHERE
	`order_items`.`order_id` IN(1, 2, 3, ...);
```

## includes

基本的には`preload`を実行
下記いずれかの条件を満たす場合は`eager_load`を実行
・`includes`したテーブルでwhere句などを使用して条件を絞った場合
・`includes`したassociationに対して、`joins`か`references`を呼んでいる場合
・任意のassociationに対して`eager_load`メソッドを呼んでいる場合


## めっちゃ簡単に使い分けするなら
・order :order_items(1 : n)など関連データがhas_manyの関係の場合`preload`
・store_accounts : user(n : 1)など関連データにbelongs_toの関係の場合`eager_load`
・指定したassociationに対してwhereしたいなら`eager_load`か`includes`

## まとめ
ただ動くコードを書けばいいのではなく、意味を理解してパフォーマンスも意識して実装しなきゃですね。
自身の理解のため端折って書いてる部分もあるので指摘があれば教えていただけますと幸いです！
詳しく理解されたい方は[参考記事](https://qiita.com/k0kubun/items/80c5a5494f53bb88dc58)をご参照ください。
いつの間にかPhpStormからGitHubのPullRequestが見れなくなった時の対処[Could not connect to repository]

# エラー内容

以下のようなエラーがPHPStormに表示されました
PhpStorm:　2023.1.5
```
Could not connect to repository github.com/YOUR_ORG/YOUR_REPO with account github.com/YOUR_USER_NAME Request response: Access to this site has been restricted. If you believe this is an error, please contact https://support.github.com.
```

![スクリーンショット_2024-11-09_17_25_57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/403635c4-d60a-6554-d199-94aa7079c03b.png)

# 対処方法

PhpStormをバージョンアップする

GitHubの仕様が変わったため、PhpStormのバージョンを上げる必要がありました。

> Github blocked IntelliJ IDEs from accessing pull requests functionality as a mitigation of security issue described in our blog


# 参考情報
参考：https://youtrack.jetbrains.com/articles/SUPPORT-A-86/Invalid-authentication-data-while-working-with-GitHub-Pull-Requests-functionality?_gl=1*1pvdgj*_ga*MTk0MTc3MzY4NS4xNzMxMTM5ODQw*_ga_9J976DJZ68*MTczMTEzOTgzOS4xLjEuMTczMTE0MDgwNC4wLjAuMA..
<Serverって何してくれんの？>

<h1>はじめに…</h1>

この記事の目的は初学者である自分の、学習内容の整理・備忘録を目的にしています。
記事に関して誤記があるかと思いますがご容赦願います。:pray:

<h2>サーバーてそもそも何してくれんの？</h2>
サーバーとはそもそも「Serve=提供する」を語源にしている単語です。
サーバーはコンピューターの仲間ですが、一般家庭用ではなく業務用の大容量・高耐久の専用コンピューターです。

▽サーバーにもいくつかの種類があり、下記の様に用途によって使い分けがなされています
<dl>
<dt>ファイルサーバー</dt>
<dd>ファイルを貯蔵するためのやつ
<dt>プリントサーバー</dt>
<dd>プリント要求にこたえるやる</dd>
<dt>データベースサーバー</dt>
<dd>情報貯蔵・要求に応じて情報提供</dd>
<dt>認証サーバー</dt>
<dd>ログインの認証を行う</dd>
…etc
</dl>

※サーバーは普段、大量のアクセスを受付し必要な情報を希望者へ提供する仕事をしているので「長時間（不休）:runner:」「高耐久（長く使える）:timer:」「高可用性（障害にも強い）:muscle:」という要素が求められる。

***

<h3>サーバーOSの種類とOSの役割</h3>
上記でいくつかサーバーの用途について触れましたが、それらの用途に合わせて”OS”というものを選定する必要があります。
サーバーはハードウェア（機械）のみではソフトウェアを稼働させることが出来ず、用をなさないのです。

OSとは…OperationSystemの略で、アプリケーションを動かすにあたり、画面表示やファイルの読み書きなど、共通する機能をまとめて効率よくするための「基本ソフトウェア」です。

ハードウェアを制御したり、ソフトウェアの動作をサポートしたり、サーバーも”OS”がないと仕事（動作）が出来ません。

▽OSの主な役割▽
①共通機能の提供
→ファイルの入出力や画面制御
②タスク管理
→実行中プログラム（タスク）の管理（切り替えたりスケジューリングしたり）
③メモリ管理
→空いているメモリをとあるプログラムに割り当てたり、解放したりして限られたスペースを有効活用する
④リソース管理
→PC上で稼働してる複数のプログラムが競合しないよう、排他制御をしてリソースを円滑に利用できるようにする


▽サーバー用OSの代表的な種類▽
<dl>
<dt>Windows</dt>
<dd>PC用OSとサーバー用OSの２種類が展開されている</dd>
<dt>MacOS</dt>
<dd>Apple製PC用のOS。現在はPC用OSしか展開していない</dd>
<dt>Linux</dt>
<dd>オープンソフトウェアで、安全性や安定した稼働からサーバー用として広く利用されている。</dd>
</dl>


<h3>まとめ</h3>
※OSは前述のとおり、サーバー稼働にとても重要な役割をいくつも果たしており、特に重要なのが「多数処理を同時並行出来る能力:v:」「高いセキュリティ能力:cop:」だとされています。

サーバーは普段の生活にはあまり目にしませんが、あらゆるサービスを提供していて、
「〇MAZONで買い物をする」「〇UISCAで電車に乗る」「クレジットカードで決済をする」などで活躍しています。
もしもサーバーがダウン（障害発生）すると…利用者には大変な機会損失が発生してしまうものです。

サーバー・OSの組み合わせによってたくさんの用途の●●サーバーに変身する事も理解ができました！


<h2>おわり</h2>
初記事の為、起承転結の構成がいまいちですね…。お恥ずかしいです。
次回に向けて精進します
Azure OpenAI gpt-4o-mini を活用してクリップボードの内容から爆速で回答を得る

# Azure OpenAIで実現する⚡️爆速情報検索活用⚡️

:::note info
本記事は、Azure OpenAIやAnthropic Claude、Google VertexAI GeminiなどのGenerative AIを活用して日々の業務生産性を向上させたい方向けの内容です。
特に、業界・業種・学生などを問わずおすすめです。🎯
:::

## 👤 著者プロフィール

| 項目 | 詳細 |
|:--|:--|
| 使用デバイス | 主にMac |
| 業務内容 | IT営業（提案書作成、製品デモ制作） |

## 🤔 よくある課題

皆さんも日々の業務で以下のような経験はありませんか？

- Google検索やPerplexityなどのWeb RAGサービスで調べ物 🔍
- 簡単な用語確認のためにブラウザを立ち上げる手間 ⏱
- **「ブラウザを立ち上げるほどでもないけど、AIにさっと聞きたい！」** というモヤモヤ 💭

## 💡 解決策

私が採用しているのは、**Azure OpenAI GPT-4o mini**を使った爆速質問回答システムです。

### なぜAzure OpenAI GPT-4o mini？

<summary>選定理由 📋</summary>

- **Azure採用理由**: 会社契約のAPIが利用可能
- **GPT-4o mini採用理由**: コスト・速度・精度の最適なバランス


## 🛠 実装方法

### システムの流れ

1. クリップボードに質問を保存
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214013/b144d109-1e62-e68a-3bdc-f4c5c5d6e19d.png)
2. Pythonスクリプトで質問を取得・API送信
3. 回答を自動でクリップボードに保存
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214013/5278ca25-7467-de3a-dc92-ff6e0e387a07.png)

### コード実装

```python:Python
import os
from openai import AzureOpenAI
import subprocess
import pyperclip
import re

# クリップボード取得
userPrompt = pyperclip.paste()

# システムプロンプト定義
systemPrompt = """
ユーザーから与えるられる質問やテーマに対して3行程度で簡潔に回答してください。
"""

# Azure OpenAI クライアント設定
client = AzureOpenAI(
    azure_endpoint = "YOUR_AZURE_ENDPOINT",
    api_key="YOUR_API_KEY",
    api_version="YOUR_API_VERSION"
)

# プロンプト作成と送信
userPrompt = "今回の質問は、" + pyperclip.paste()
response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[
        {"role": "system", "content": systemPrompt},
        {"role": "user", "content":userPrompt}
    ]
)

# 回答をクリップボードに保存
pyperclip.copy(response.choices[0].message.content)
```

## 🔥 活用のコツ

1. **Alfred連携**: クリップボードのプレビュー機能で即座に回答確認 👀
2. **エイリアス設定**: `python sample.py`などをショートカット化 ⌨️
3. **プロンプト設計**: 簡潔な回答を得られるよう指示を工夫 📝

## ⚠️ 注意点

:::note warn
- Azure OpenAIの環境設定は別途必要です
- 社内のセキュリティポリシーに準拠したAPI利用を心がけましょう
:::

## 🎉 まとめ

このシステムを導入することで:
- 概要だけで良いからサクッと情報を把握したい時のブラウザ起動の手間を削減 ⚡️
- 業務フローの中断を最小限に抑制 🔄
- 素早い情報アクセスを実現 🚀

ぜひ皆様の業務効率化にお役立てください！ 🙌

---

> 本記事に関するご質問やご意見がありましたら、コメントにてお気軽にお寄せください。
久しぶりに触れるサーバ。フルバックアップを取ろう。

# 久しぶりにサーバに触れた

今回のソースはCopilot先生です。
最近はPMO業務にいそしんでいたため全く触れていなかったサーバ。
今回Redmineを搭載したいということで、再度触り始めました。

# 自動バックアップを取ろう

まず、サーバにログインして、以下コマンドを実施。
> Sudo dnf install rsync

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3781397/7a80ed2c-519b-4fb1-94d0-30e7611fd98d.png)

> y

これでよろしいので、実行⇒完了
どのディレクトリをバックアップすればいいか、忘れたな…
フルバックアップにするか。

>sudo mkdir -p /backup/full_backup

フルバックアップ用のディレクトリを準備。

> sudo rsync -avxHAX --delete --exclude=/backup / /backup/full_backup

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3781397/5d804f55-d4af-e42e-1f2c-253457fdac99.png)
こんな感じの表記が出たら成功です。

つぎに復元の手順を確認。

> sudo rsync -avz /backup/full_backup/ / 

これで良いらしい。一度テストしたい。
1. テスト用ファイルを作成し
2. フルバックアップを取得
3. テスト用ファイルを削除し
4. フルバックアップから復元
を実行してみたところ、上手く復元できていた。
※既存のものをバックアップ前に合わせて消すことはしないということのようだ。

また、毎日午前２時にフルバックアップを取るcronジョブを設定したい。

まず、以下コマンドを実行
> crontab -e

"/tmp/crontab.xxxxxx"ファイルに記述を始めるようになる。
> 0 2 * * * sudo rsync -avxHAX --delete --exclude=/backup / /backup/full_backup

と記述して終了。

# ついでなので、各種パッケージを更新しておこう。

> sudo dnf check-update

> sudo dnf upgrade -y

> sudo reboot
【集中方法】Focus On Methods  - 試行錯誤して見つけた集中力を高めるメソッドたち

# 始めに
お久しぶりです、るんるんです。
皆さんは集中できないと悩んだことはないですか？
私は何度もあります。その度に何か **Focus On Method** (=集中するための行動) がないかと色々な方法を模索しました。
その中から、ある程度効果があったものを列挙して、さらにそれらを一つひとつ評価して行きたいと思います。
どうか最後までお付き合いください。


いいね貰えると嬉しいです！🥰

こちらにも様々な記事を公開しています。ぜひご覧ください！！

https://runtech-blog.netlify.app/

# 結論
最初に結論を申し上げると、

#### 水を飲め

です。
どうしてこのような結論になったのか、読み上げて貰えればと思います。

# 判定方法

これから様々なメソッドをご紹介しますが、まずは判定方法について説明します。

- **オススメ度**: 星3つで判定する。各項目の総合的評価
- **手軽さ**: すぐにできるか、時間をどれだけ要するか、特別なものが必要か、etc
- **効果**: 集中へどれだけの効果をもたらすか(筆者の経験)

ルールとしては、「異論は認めるが、あくまで異論」です。
では参りましょう。

# Focus On Methods
## 運動
散歩やランニング、ジムなど。筆者は午前中の集中が切れたタイミングで行く。

#### オススメ度: ⭐️⭐️

##### 手軽さ
運動の程度によるが、散歩やランニングなら、15~30分
ジムだと、行き帰り合わせて1時間ほどかかる
座っている椅子からわざわざ立ち上がって運動するのは、まぁまぁ腰が重い

##### 効果 
帰ってきてすぐにデスクに座ることで、1時間程度の集中が見込める
頭がリフレッシュされているのを実感できる

##### 特筆事項
- 言わずもがな健康的な副次効果が見込める


## 寝る
言わずと知れた、人間の最も必要な行為の一つ
ここでは昼寝を対象とする
### オススメ度: ⭐️⭐️⭐️
15分から30分を要する。
人によってはできない行為ではある(会社が積極的に導入すべきだと思うが...)

##### 効果 
効果は絶大。昼寝後の1~2時間はゴールデンタイム。

##### 特筆事項
- 眠たくなくても寝る
- 寝過ぎは禁物


## 瞑想する
家族にやっているところを見られるとちょっと恥ずかしい、あれ

#### オススメ度: ⭐️

##### 手軽さ 
座って目を瞑るだけ。できるだけ作業する椅子ではない方が良い。
瞑想という行為自体、難易度が高い。
人のよっては1時間できるらしいが、超人だけである。

##### 効果
そこまで集中力が増したと実感できなかった

##### 特筆事項
- 筆者流瞑想:
    - 目を瞑って、呼吸に集中する → 違うことを考えてしまう → 認識する → 呼吸に集中する
    - このサイクル
- 目的は2つ
    - 自分が今何を感じているのかを認識する
    - 呼吸から思考が離れていることを認識して、引き戻す作業
- こう見ると集中力を高めるのが目的ではないような気がする


## 場所を変える
移住のススメ

#### オススメ度: ⭐️⭐️

##### 手軽さ 
これは人による。
フリーアドレスを採用している会社ならできるし、そうでないならできない
リモートでも、複数部屋があればできるし、ないならできない

##### 効果
効果はかなり期待できる。家の中で場所を変えるだけでも、効果を実感できる

##### 特筆事項
昇降デスク等を使用して、立ち作業に切り替えるだけでも効果がある


## 時間を決める
いわゆるポモドーロ・テクニック。25分作業5休憩のサイクルを回す。8時間勤務なら16サイクル。

#### オススメ度: ⭐️

##### 手軽さ
アプリ等も出ているので、導入するだけで実行はできる

##### 効果 
最初のうちは実感できる。
だんだんダラける傾向にある ←自分が悪い


## とりあえずやる
スマブラの父・桜井政博さんも紹介していた方法 →[とにかくやれ!! 【仕事の姿勢】](https://youtu.be/JV3KOJ_Z4Vs?si=g1rCrxddrLaDGye-)
始める際のハードルをとにかく下げるのがコツ

### オススメ度: ⭐️⭐️

##### 手軽さ
意識の腰を持ち上げるだけ。
始めるハードルをできるだけ下げる(e.g. 簡単なレビューの修正だけやる)

##### 効果
意外とある。自分を騙せた人の勝ち

## やることを決める
1日のTODOを決める
#### オススメ度: ⭐️⭐️

##### 手軽さ
紙とペンがあれば良い。紙に今日やることを全て書き出すだけ。
タスクの粒度はある程度細かい方が良い。
作業中常に見えるところに置いておく。

##### 効果
終えたタスクに線を引くたびにモチベーションが上がる。
##### 特筆事項
- パソコンや携帯、iPad よりも紙が良い
    - 紙は、常に表示されている唯一のデバイス(?)です
    - パソコンに ToDo を書き出しても良いですが、常に表示されている効果かなり大きいです
    - 自分はパソコンやiPad 等でもTODO管理を試しましたが失敗しました
- 仕事終わりに残課題等を整理しておくと、次の日のこの作業がすごく楽になる


## 水を飲む
説明不要

#### オススメ度: ⭐️⭐️⭐️
##### 手軽さ
水を飲むだけ
所要時間1分未満
家の中でも大きい水筒を持ち歩くと、なお手軽さが増す

##### 効果
継続的な集中力が見込める。逆に水分不足だと集中できない。

##### 特筆事項
- トイレに行きたくなるが、これは散歩として捉えることもできる。
- 腸や肌にもとんでもない効果をもたらす。


# 総括
如何だったでしょうか。「水を飲む」をとにかくオススメしたくてこの記事を書きましたw
誰得ですが、今の私は以下のような感じで仕事を進めてます。
![mermaid-diagram-2024-11-09-162754.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518711/daa12d8c-41c6-ea8d-7ee6-f42291112757.png)

何か参考なれば幸いです。
水を飲むは本当にオススメなので、これだけでも真似して頂きたいなと思います！
【ROS2】壊れたbagを修復する

https://github.com/ros2/rosbag2/issues/1029#issuecomment-1497442077

metadata.yamlが壊れていて

```
$ ros2 bag info /path/to/bag
Exception on parsing info file: yaml-cpp: error at line 1, column 3: unknown escape character:
```

reindexにも失敗する

```
$ ros2 bag reindex /path/to/bag
[INFO] [1731135419.165427003] [rosbag2_cpp]: Beginning reindexing bag in directory: /path/to/bag

closing.

closing.
[INFO] [1731135419.182126217] [rosbag2_storage]: Opened database '/path/to/bag/file.db3' for READ_ONLY.
[1]    27536 segmentation fault (core dumped)  ros2 bag reindex /path/to/bag
```

そんなときは

```
$ mv /path/to/bag/file.db3 /path/to/bag/file.db3.bak
$ sqlite3 /path/to/bag/file.db3.bak ".recover" | sqlite3 /path/to/bag/file.db3
$ ros2 bag reindex /path/to/bag
```

こう！

上の手順も通用しない場合は以下のコメントを参考にsqlite3のコマンドを叩くとなんとかなるかもしれません（sqlわかりません）

https://github.com/ros2/rosbag2/issues/1029#issuecomment-1310291025

そもそも普通にCtrl-Cでrecord止めてるのに壊れるのなんなんだ？
Prismaでmigrateが終わらない原因

# 概要
Supabase/Prismaでマイグレーションする際、下記のコマンドを実行します。
```
npx prisma migrate dev --name init
```

ですが、、、**なぜかmigratesフォルダが作成されない現象**が発生しました。<br>下記のような表示がでるが反応がない、、
```
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "<database_name>", schema "<schema_name>" at "<database_host>:<port>"

```

なかなか解決しなかったので、解決方法を共有できればと思います。

# 原因と解決方法
結論、**DATABASE_URLで設定したポートの番号に誤りがあるようです。**
Prismaでセッションを行う際、セッションモードである必要があるため、**ポート番号を5432にする必要がある。**


なので、DATABESE_URLに設定したurlのポート番号を5432にすることで解決すると思います。

下記に一例を載せておきます。

```
DATABASE_URL="postgresql://<user>:<password>@<supabase-host>:5432/<database_name>"

```
個人の感想ですがハンズオンを開催した時のあるある4選

こんにちは。Kaneyasuです。
（まだ年末じゃないけど）今年は複数回ウェビナーやハンズオンの講師をやらせていただきました。
今回はそこから学んだ自分的ハンズオンあるあるを書いていきます。

# ハンズオンの需要について

まずハンズオンの需要について述べておきます。
ハンズオンは、基本的に主催者・参加者の方両方にウケがいいです。
表面的には、実際に手を動かすトレーニングなので得られるものがわかりやすく、参加者の満足度が高まりやすい、というのが理由ですが、もうちょっと深く考えると以下のことがあるように感じています。

- 最初の一歩を踏み出すハードルがある。モダンな技術になるほど、その傾向が強い。
- 技術のつまみ食い、独自流で覚えてしまっている人が意外と多い。

後者は多忙だったり、組織の事情でそうせざるを得ない場合もあります。
最初の一歩を踏み出し、知識を学び直すという意味で、ハンズオンは需要が高いようです。

では、次項からハンズオンあるあるを紹介していきます。

# 1. 過去のドキュメントが役に立たない

AWSを始めとしたクラウドサービスで、よくあります。
1年ぐらい前のドキュメントだとUIや仕様が変わっていることが多いですね。

デザインが変わるのはまだいいですが、厄介なのは設定項目が増減している場合があります。
想定外の動きをすると、進行に支障をきたすので、最悪画面ハードコピーをカットしてでも、仕様変更を追いかける方をお勧めします。

# 2. ドキュメントの画面ハードコピーの数がエグい

ハンズオンのドキュメントだけで全て担えるマニュアルのノリで書いてしまうとこうなります。
丁寧な故にこうなることもありますが、説明・デモの失敗リスクを避けすぎる側面もあると感じています。

これは、前述の通りツール・サービスの変更が入った場合のメンテ負荷を増加させてしまい、ハンズオンというサービスの再現性を下げてしまうことにも繋がります。
ハンズオンの意義から見ても、ドキュメントを読めばできてしまうのならば、ハンズオンをしなくてもいいのでは？とも思えます。

# 3. 書く人によってドキュメントの記述粒度が異なる

ハンズオンのドキュメント作成を分担するとこれが起きることがあります。
特にメイン講師とそれ以外の方で分担すると、当事者意識にどうしても差があるため、それがドキュメントにも表れてしまうわけです。

取り急ぎ言えることは、当事者意識の差は言っても変わるものではないので、メイン講師はドキュメントの粒度の差にイラつかないようにしましょう（汗）

# 4. 参加者ごとの環境差でトラブる

オンラインでハンズオンすると割と起きます。
ハンズオンにあたり、ある程度端末の条件を提示するのですが、社内プロキシやOSは合っているけれど実は仮想マシンやVDIです、という時があります。
環境差によるトラブルは短時間では解決しないことが多いので、これが起きたら進行優先で進めるしかないですね・・・。

これの対策のために、以前はWeb IDEのCloud9を使っていたことがありますが、新規受付が終了してしまったので、今まさに悩んでいるところです。

https://aws.amazon.com/jp/blogs/devops/how-to-migrate-from-aws-cloud9-to-aws-ide-toolkits-or-aws-cloudshell/

個人的にGitHubやGitLabのWeb IDEを検討していて、使い勝手がある程度まとめられたら記事にしたいと思っています。

https://github.com/zvizvi/GitHub-Web-IDE

https://docs.gitlab.com/ee/user/project/web_ide/

# 本記事におけるあるあるの傾向とまとめ

4番目はともかく、1～3番目は講師としての未熟さによるあるあるかなと思います。
未熟さのカバーをドキュメントを作り込むことに求めているのがよくないのかもしれませんね。

ドキュメントで完結するならばハンズオンの意義は薄いので、再現性を意識してちょうど良い粒度のドキュメントにとどめ、講師としてのスキルアップに向き合うのが正しそうです。
rails new [プロジェクト名]コマンドで作成したアプリがGitHubにプッシュできない時の対処法

## はじめに
以下のrails newコマンドで作成したプロジェクトがGitHubにプッシュできず困ったので、同じエラーに悩まれている方の手助けになればと思い、記事に残すことにしました。
```bash
rails new rails-app
```

## まずは結論
結論から言うと、rails newコマンドで.gitファイルがrails-appディレクトリ内に自動的に作成されていて、それがGitHubではサブモジュールとして扱われてしまうことが原因でした。作成された.gitを削除することで解消しました。

## エラー状況

```bash
git add rails-app
```
上記を実行すると、以下のように表示されます
```bash
error: 'rails-app/' does not have a commit checked out
fatal: adding files failed
```

## エラー対処
### 1. ディレクトリ内のファイルを確認
```bash
ls -a rails-app/
```
**実行結果**
![スクリーンショット 2024-11-09 16.05.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3535387/17709efd-2235-0841-dad6-1a14830bd8af.png)

### 2. 「.git」ファイルの削除
```bash
rm -rf rails-app/.git
```
念のため確認⇩
```bash
ls -a rails-app/
```
**実行結果**
![スクリーンショット 2024-11-09 16.13.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3535387/6ca85b05-6940-6181-e178-e9538c6eeea4.png)

上記の状態で、git addコマンドを実行すると問題なくステージングできました。

## おわりに
チャットGPTにエラー文のみを貼り付けて聞くと、サブモジュールを確認して初期化と更新をする方法やキャッシュを消去する方法を提案されるのですが、一向に解決せず時間がかかってしまいました。
サブモジュールについて触れられた場合について、以下もおまけで追記します。
> ```bash
> git submodule status
> ```
> git submodule statusで何も表示されない場合、rails-app/がサブモジュールとして正しく設定されていない可能性があります。ただし、Gitは依然としてrails-app/をサブモジュールと認識しているようです。

最後までお読みいただき、ありがとうございました！
この記事が少しでもお役に立てれば幸いです。誤り等ありましたら、ご指摘ください。