OmniAICreator/Qiita-1.07M huggingface dataset:
AtCoder Beginner Contest 339 振り返り

# ABC339
## 概要
https://atcoder.jp/contests/abc339

## A - TLD
__考えてたこと__
最初は文字列に対してfor文使って`.`以降の文字を全て出力してました。この場合`.`が2回以上入っているケースで失敗することにテストケースで気づきました。
そのため、文字列を一回反転させて`.`が出るまで取得し`.`出たタイミングでbreak, 取得した文字を反転でAC。

__提出したもの__
```c++:a.cpp
int main() {
    string s;
    cin >> s;
    reverse(s.begin(), s.end());

    string ans = "";

    fore(a, s) {
        if (a == '.') {
            break;
        }
        ans += a;
    }
    reverse(ans.begin(), ans.end());
    cout << ans << endl;
    return 0;
}
```

__振り返り__
解説のfor文を2回回すやり方よりはこっちの方が好きかもです。 

## B - Langton's Takahashi
__考えてたこと__
glid移動系だから、最近気に入ってるdirectionを配列で持っておいてkeyを使って進行方向を管理する方針でいこうと早い段階で決めました。ただ、実際に解いてみるとdirectionの設定を間違えたこと、トーラス状のグリッドの設定がうまくできなかったことから実装はかなり苦戦しました。

__提出したもの__
```c++:b.cpp
int main() {
    // input
    int h, w, n;
    cin >> h >> w >> n;
    char glid[h][w];
    rep(i, 0, h) {
        rep(j, 0, w) {
            glid[i][j] = '.';
        }
    }
    int h_now = 0;
    int w_now = 0;
    int h_direction[] = {-1, 0, 1, 0};
    int w_direction[] = {0, 1, 0, -1};
    int directionKey = 0;

    for (int i = 0; i < n; i++) {
        if (i != 0) {
            h_now = (h_now + h_direction[directionKey]) % h;
            w_now = (w_now + w_direction[directionKey]) % w;
            if (h_now == -1) {
                h_now = h - 1;
            }
            h_now %= h;
            if (w_now == -1) {
                w_now = w - 1;
            }
            w_now %= w;
        }
        if (glid[h_now][w_now] == '.') {
            glid[h_now][w_now] = '#';
            directionKey = (directionKey + 1) % 4;
        } else {
            glid[h_now][w_now] = '.';
            if (directionKey == 0) {
                directionKey = 3;
            } else {
                directionKey = directionKey - 1;
            }
        }
    }

    // output
    rep(i, 0, h) {
        rep(j, 0, w) {
            cout << glid[i][j];
        }
        cout << endl;
    }
    return 0;
}
```
__振り返り__
解説見たらトーラス状のグリッドがやっぱり強引だったかも...と思いました。マイナスになった時は元の大きさ足す(`x+=h`, `y+=w`)みたいにすれば良かった。directionKeyに関しても-1じゃなくて+3にして余りを取ることで整えるという解説の形がすごく参考になりました。

## C - Perfect Bus
__考えてたこと__
簡単そうだと思ったら簡単だった問題。とりあえず全部足してマイナスになるならその最小値を保存して最後に絶対値を足したら良いんじゃないかと思ったらそうだった。

__提出したもの__
```c++:c.cpp
int main() {
    int n;
    cin >> n;
    ll now = 0;
    ll now_ans = 0;
    rep(i, 0, n) {
        ll num;
        cin >> num;
        now += num;
        now_ans = min(now_ans, now);
    }
    cout << abs(now_ans) + now << endl;
    return 0;
}
```

__振り返り__
最初から計算してマイナスになったタイミングで辻褄を合わせるためにもっと人が乗っていたことにする、みたいな回答を直感で導き出せて良かったです。

## 感想
B問題かなり時間がかかっちゃったのでもっと丁寧な実装を心がけて素早く解きたい...。
PythonでPC起動時間を管理するものを作成した

PCをつけたまま忘れてしまうという方のために作った
マウスを1時間動かさないとシャットダウンされて起動終了がLINEの通知に行くようにした

```ruby:Python
import os
import logging
import PySimpleGUI as sg
import pyautogui
import time
from plyer import notification
from module import ActiveWindows
from module import pykit_tool 
from module import pysns_tool

def sendlog(msg):
    line = pysns_tool.get_json(fle=r"data.json",key="line")
    btr = pykit_tool.batterry()
    txt = f"{btr} {msg}"
    logging.info(txt)
    pysns_tool.send_line(line,txt)
    
class Shutdown:
    def __init__(self):
        self.set_timer = 60
        self.position = []

    def set_sht_limit(self, sht_limit):
        self.sht_limit = sht_limit * 60
        


    def set_gui(self):
        sg.theme("DarkBlue")
        # GUIのレイアウトとウィジェットを定義
        layout = [[sg.Text(self.sht_limit, key='time')],
                  [sg.InputText(key='-Input-', size=3), sg.Button('分')]]
        
        window = sg.Window('Shutdown Timer',
                            layout,size=(90,70),
                            location=(1270,660),
                            no_titlebar=True,
                            alpha_channel=0.8,
                            grab_anywhere=True,
                            keep_on_top=True,
                           
        right_click_menu=['Unused', ['ActiveON', 'ActiveOFF','!&Click', 'Exit',]],right_click_menu_text_color='green')
        # イベントループ
        while True:
            event, values = window.read(timeout=1000)
            if event == sg.WIN_CLOSED or event == 'Exit':
                break
            elif event == sg.WIN_CLOSED or event == 'ActiveON':
                ActiveWindows.activewindow(0)
            elif event == sg.WIN_CLOSED or event == 'ActiveOFF':
                ActiveWindows.activewindow(1)

            # 時間を更新
            self.sht_limit -= 1
            warntime = 60
            #残り60秒なら通知
            if self.sht_limit == warntime:
                pykit_tool.send_notification(f"残り{warntime}秒です")
            elif self.sht_limit == 0:
                break
            m, s = divmod(self.sht_limit, 60)
            window['time'].update(f"{m}分{s}秒")

            # マウス位置を取得
            position = pyautogui.position()

            # マウス位置が変化したら時間をリセット
            if position not in self.position:
                self.position.append(position)
                self.set_sht_limit(self.set_timer)

            # 入力された時間を読み込み、カウントダウンを開始
            if event == '分':
                try:
                    sht_limit = int(values['-Input-'])
                    self.set_sht_limit(sht_limit)
                except ValueError:
                    pass

        window.close()

    def count_time(self):
        # 時間経過処理
        while self.sht_limit > 0:
            time.sleep(1)
            self.sht_limit -= 1

        # 時間切れ処理
        print('時間切れです!')

    


if __name__ == '__main__':
    pykit_tool.setup_logging(r"media\job.log")
    sendlog("起動")
    shutdown = Shutdown()
    shutdown.set_sht_limit(60)
    shutdown.set_gui()
    shutdown.count_time()
    sendlog("終了")
    os.system('shutdown -s')
    

```
UE5 カプセル形状にマスク抜きを行う

# 概要
今回実装するのはカメラからプレイヤー間のメッシュがカプセル形状にマスクして、
プレイヤーを見えるようにします、図にすると以下のようになります。
![Capsule.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156053/9dbdb46c-9e58-d4c6-1074-c6d65b816ab2.jpeg)


# 実装
### マテリアルパラメータコレクションを作成(MPC)
次に作成するマテリアル関数内でプレイヤーの位置と半径が必要なのでMPC「MPC_Player」作成します。
![MPC.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156053/a61d8b6c-a081-d642-7b37-690f85251079.jpeg)

### カプセル形状にオブジェクトをクリップする関数を作成
マテリアル関数「MF_CapsuleShape」を作成して以下のようにノードを組みます。
![MF_CapsuleShape.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156053/5570642d-dade-1764-8bc4-71dac2cc4dbb.jpeg)

### マスク用マテリアル作成
マスク用のマテリアルを作成します。
まずは、「Blend Mode」を「Masked」して以下のようにノードを組みます(テクスチャは適当です)。
![Block.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156053/332d6c6e-3fed-8026-fb58-5b824e79bca4.jpeg)
「Shadow Pass Switch」は影の不具合がでる＆負荷軽減のため影には反映させないようにしています。
作成したら、対象のスタティックメッシュに割当ましょう。

### オーバーレイマテリアルを作成
そのままだと中から外が見えるので、中から見えないようにするマテリアルを作成します。
まずは「Two Side」にチェックを入れ「Blend Mode」を「Masked」に「Shading Mode」は「Unit」にします。
![TwoSideAndShadingModel.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156053/e135176d-f13e-7e7f-281f-0880778a377b.jpeg)

マテリアルは以下のようの組みます。
![Black.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156053/41a825b6-dfc5-9341-cafc-5fa2fbd1af22.jpeg)

作成できたら対象のスタティックメッシュのオーバーレイマテリアルに割当ましょう。

### MPCにプレイヤー中心位置を格納
「BP_ThirdPersonCharacter」のTickイベントでプレイヤーの中心位置をMPCに入れます。
丁度「Camera Boom」の座標がいい位置にあるので利用します。
![PlayerPos.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156053/dde06ed7-7857-4453-ec81-58c86122cd25.jpeg)


# 結果
![Result.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156053/f6d6af81-c8f6-9443-dc22-d75ac37d7f01.gif)


# まとめ
カプセル形状にメッシュをマスク抜きできました。
これでゲーム中のプレイヤーの視認性が上がるといいですね。

# 参考
https://iquilezles.org/articles/distfunctions/
wslで、最小のカーネルをコンパイル  その2

# 概要
wslで、kernel.elfのコンパイル、やってみた。
QEmu で、実行してみた。

# 環境
Windows10

# 手順

# diskexplorerで、test4.elfを入れる。

![スクリーンショット 2024-03-09 204400.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/c1a75da0-76ec-d347-7ce8-73c12d9bc48c.png)


# QEum Luncharで、bootgrub.imgを起動

![スクリーンショット 2024-03-09 173930.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/7a189c6f-c5b2-b577-6071-785bfae94c27.png)

Cキーで、コマンドラインに入る
kernelを設定
bootで起動

```
grub> kernel (fd0)/boot/test4.elf

grub> boot
```

![スクリーンショット 2024-03-10 162742.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/48eb7c1a-2d6c-af1f-d996-57fd67dc2a99.png)

# kernelが起動

Hello world!
![スクリーンショット 2024-03-10 162758.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/5356368c-54de-c998-ec5b-05412c8f2a8b.png)

以上。
[Windows Server 2019]ライセンス条項が見つかりません。

こんにちは！れーあです。

VMware Workstation Player上にWindows Server2019をインストールしようとしたらこんなエラーが出てきました。
![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632150/96e0e347-97cf-f031-0d7e-82cf17c70160.png)
> マイクロソフト ソフトウェア ライセンス条項が見つかりません。インストール元が有効であることを確認し、インストールを再実行してください。

なんだこれはとなったため、本記事を投稿します。

それではどうぞ。

## この記事の要約
- フロッピーディスクを削除しないとインストール失敗する

## 前提情報
- <b> VMware Workstation Playerバージョン：17.5.0 </b>
- <b> OS：Windows Server2019 </b>
 17763.3650.221105-1748.rs5_release_svc_refresh_SERVER_EVAL_x64FRE_ja-jp.iso

## 対処方法
ではエラーの解消方法を記載します。

<b> ① Windows Server2019はひとまずパワーオフ状態にします。 </b>
![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632150/892a3a85-db65-2915-ab7f-488935796102.png)


<b> ②「仮想マシン設定の編集」をクリックして、仮想マシン設定画面を表示します。</b>
![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632150/1691b0ba-2f36-3b2b-75ac-f2b9f1ce00c4.png)

<b> ③「ハードウェア」の「フロッピー」を選択後「削除」をクリックしてフロッピーディスクを削除します。 </b>
![005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632150/9e613b8e-67e6-3dee-4561-81ebd4454daa.png)

<b> ④「OK」をクリックして、仮想マシン設定画面を閉じます。 </b>

<b> ⑤ Window Server2019のサーバを起動します。 </b>

<b> ⑥ インストール言語や時刻等の設定画面が出てきたら成功です。 </b>
![006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632150/eaf2ceec-3346-2c39-b4e6-195698c6514e.png)

## 原因
OSをインストールするためにはまずisoファイルを使用します。これは光ディスク用のアーカイブファイルなので、CD/DVDメディアで読み込まれます。
しかし、VMWware Workstation PlayerでWindows Serverの仮想マシンを作成した際、デフォルトではフロッピーディスクドライブも一緒につけてしまうようです。
このフロッピーディスクがブート時、最初に読み込まれるため、インストールしようとするとCD/DVDメディアのisoファイルをうまく読み込めないという事象が発生するようです。
検証したところ、フロッピーディスクドライブは削除ではなく「起動時に接続」のチェックを外すだけでもよいですが、使用しないデバイスを付与しているのもあまり望ましくないため、削除が無難と思われます。

## おわりに
Window Serverは評価版インストールのため、ライセンスは使用しないのになぜ今回のような文言がでるのだろうと疑問に思っていたのですが、解消できてよかったです。ブート順序を変えるとかでもいけるのかもしれないですが、それは物理機器へのインストールの時に考えようと思います。


## 参考
https://itc-engineering-blog.netlify.app/blogs/win2019error

https://medium.com/certifried-it/how-to-install-windows-server-2019-in-a-vm-with-vmware-b20b80a8bcd5
Pythonでバッテリ残量とメモリ残量を出力してみた

普段PCを落とさないためメモリやバッテリ残量が気になったので作成してLINEに飛ばすようにした

バッテリー残量
```ruby:Python

def batterry():#バッテリ残量を表示
    import psutil
    dsk = psutil.disk_usage('/')
    btr = psutil.sensors_battery()
    btr = f"{btr.percent}%"
    print(btr)
    return btr

```
メモリ残量
```ruby:Python
def disk_usage():  # ディスク使用状況を表示
    import psutil
    path = '/'
    disk_info = psutil.disk_usage(path)
    total = disk_info.total / (1024 ** 3)  # ギガバイト単位に変換
    used = disk_info.used / (1024 ** 3)
    free = disk_info.free / (1024 ** 3)
    total = "{:.2f}".format(total)
    used = "{:.2f}".format(used)
    free = "{:.2f}".format(free)
    print(disk_info)
    print(f"合計容量{total}GB")
    print(f"使用容量{used}GB")
    print(f"空き容量{free}GB")

    return total, used, free
```
これで安心
PythonでDiscordに画像を送る


Pythonで監視カメラを作ったので撮影した画像をDiscordに送りたい。

探したけどなかったので記載


```
import reqest

def send_discord(webhook_url,msg, image_path="" ):
    print("Discodeに送信中")
    try:
        with open(image_path, 'rb') as image_file:
            payload = {
                "content": msg,
                "file": image_file
            }
            response = requests.post(webhook_url, files=payload)
            response.raise_for_status()
            print("Image sent successfully")
    except FileNotFoundError:
        print("File not found.")
    except requests.exceptions.RequestException as err:
        print(f"Error sending image via : {err}")
```

いけた！
1回Fileだけしかでなかったのだがバイナリデータで送ってるからとかなんとからしい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665151/5377a164-c0ce-39a4-714a-4790bce793a4.png)
Pythonで接続しているWi-Fiの名前を取得する

使うかわからないけどWiFiの名前を取得するときできるか探したら昔の自作モジュールに出てきた、、、全然記憶にない

```
import subprocess

try:
    wifi_name = next((line.split(":")[1].strip() for line in subprocess.run(["netsh", "wlan", "show", "interfaces"], capture_output=True, text=True, check=True).stdout.splitlines() if "SSID" in line), "none")
except subprocess.CalledProcessError:
    wifi_name = "none"

print("Wi-Fi:", wifi_name)

```
指定のウィンドウをアクティブ・解除するスクリプトをしたい

コピペ大好きな自分にとってコピペ先のウィンドウを常に最前面にする必要があったので作成した。

選択したウィンドウが常に最前面かどうか取得してActiveなら解除にしたかったが見つからなかった。

```ruby:Python
import win32gui
import win32con
import time


def activewindow(wm=0):
    modify = ""
    try:
        # アクティブなウィンドウのハンドルを取得
        hwnd = win32gui.GetForegroundWindow()
        if hwnd == 0:
            raise Exception("アクティブなウィンドウが見つかりません。")

        # アクティブなウィンドウのタイトルを取得
        active_hwnd = win32gui.GetWindowText(hwnd)

        # ウィンドウの状態を変更
        if wm == 0:
            win32gui.SetWindowPos(hwnd, win32con.HWND_NOTOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE | win32con.SWP_NOSIZE)
            modify = f"ActiveOFF: {active_hwnd}"
        elif wm == 1:
            win32gui.SetWindowPos(hwnd, win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE | win32con.SWP_NOSIZE)
            modify = f"ActiveON: {active_hwnd}"
        else:
            raise ValueError("無効な入力値です。0 または 1 を指定してください。")

        print(modify)
    except Exception as e:
        print(f"エラー: {e}")


if __name__ == "__main__":
    try:
        x = 1
        print(3)
        for i in range(1,4):
            print(i)
            time.sleep(1)
            
        activewindow(x)
    except ValueError:
        print("無効な入力です。数値を入力してください。")

```
pykit_tool.send_notificationはwindowsの通知するための機能
【AWS】MFA(多要素認証)の設定

## 手順
1. ルートアカウントでログイン
1. コンソール上の検索欄に「 IAM 」と入力
1. 検索結果のIAMをクリックして、IAMのダッシュボードに飛ぶと、MFAが未設定だと以下の画面が表示されるので、「MFA を追加」をクリック
![スクリーンショット 2024-03-10 16.02.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2239673/d27ab30d-ee47-fdb3-ac9f-121d53527058.png)
1. 以下の画面に遷移するので、デバイス名とデバイスを選択します。今回選択するデバイスは、「Authenticator app」にして「次へ」をクリック![スクリーンショット 2024-03-10 16.10.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2239673/af9fb11e-1b27-f3c1-9628-d14b6ce2c05a.png)
1. 次に以下の画面に遷移したときに、「Google Authenticator」を自身のスマホ等にDLします。
![スクリーンショット 2024-03-10 16.13.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2239673/ccc762d8-4007-2c88-51de-f4936284a9ae.png)
1. DL後、②のQRコードを表示し、「Google Authenticator」で読み取り、2回分のコードを③に入力します。

## 終わり
以上がMFA認証の方法でした。
もう一度「3.」のIAMダッシュボードに遷移したときに、「root ユーザーは MFA が設定されている」にチェックが入っていれば、設定に成功してるかと思います。
pandasでcsvを読み込んだらErrorが起きた


```
import pandas as pd

def read_parameter(pflepath, mflepath):
    # CSVファイルを読み込む
    print(pflepath)
    pdf = pd.read_csv(r"C:\Users\user\Documents\Soler\para.csv", encoding="cp932")
    print(mflepath)
    mdf = pd.read_csv(r"C:\Users\use\Documents\Soler\measurement.csv", encoding="cp932")
```






cpで試してもダメだった



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665151/03a5b6cc-4f4a-9eca-c47f-304f4b5eec7f.png)


```
pdf = pd.read_csv(pflepath, encoding="shift-jis")
pdf = pd.read_csv(pflepath, encoding="cp932")
```

https://qiita.com/ponsuke0531/items/1dcfad48db1e33c16085

参考にしたけどダメだった
管理者権限のない Ubuntu 20.04 に SSH クライアントを導入する

# はじめに

管理者じゃない Linux 環境にログインしている貴方。
外とsshでお話したいのに、sshクライアントがインストールされていない...！

そんなあなたに、コピペで解決できる、sshクライアント導入方法を紹介します。

# 想定読者

* 管理者権限を持ってない、Ubuntu 20.04 ユーザー
* SSH 使って、外とお話したい

# インストール先の作成

とりあえずホームディレクトリくらいは自由にアクセスできるでしょう？

```bash
cd ${HOME}
mkdir user_installed
```

# SSH パッケージのダウンロード

```bash
cd ${HOME}/user_installed
wget http://security.ubuntu.com/ubuntu/pool/main/o/openssh/openssh-client_8.2p1-4ubuntu0.11_amd64.deb
```

# SSH パッケージの展開

```bash
cd ${HOME}/user_installed
ar vx openssh-client_8.2p1-4ubuntu0.11_amd64.deb
tar Jxvf data.tar.xz
```

# お片付け

```bash
cd ${HOME}/user_installed
rm control.tar.xz data.tar.xz debian-binary openssh-client_8.2p1-4ubuntu0.11_amd64.deb 
```

# 参考情報

最新のdebパッケージは、以下を参照して確認しましょう。

* [Package: openssh-client (1:8.2p1-4ubuntu0.11 and others) [security]](https://packages.ubuntu.com/en/focal/openssh-client)

# おわりに

特定の人に刺さると幸いです。
【Ruby】paizaラーニング問題集解答（入力値を使った演算）

# 引き算・掛け算 (paizaランク D 相当)
https://paiza.jp/works/mondai/d_rank_level_up_problems/d_rank_level_up_problems__accompanied_by_stdin_2
### 自分の解答（誤答）
```ruby:practice.rb
numbers = gets.split

A = numbers[0]
B = numbers[1]

D = A - B
P = A * B

puts "#{D} #{P}"

# Runtime error
# Main.rb:18:in `<main>': undefined method `-' for "397":String (NoMethodError)

# D = A - B
#       ^
# Did you mean?  -@
```
### ChatGPTの解答

理解しました。入力が半角スペースで区切られて1行で行われる場合、それに対応するようにコードを修正します。

```ruby
# 1行で入力を受け取り、半角スペースで分割
numbers = gets.chomp.split

# 入力が2つの数値でない場合にエラーとする
if numbers.length != 2 || !numbers.all? { |num| num.match?(/\A-?\d+\z/) }
  puts "正しいフォーマットで2つの数値を入力してください。"
  exit
end

# 数字に変換
A = numbers[0].to_i
B = numbers[1].to_i

# 引き算と掛け算
D = A - B
P = A * B

# 結果の表示
puts "#{D} #{P}"
```

このコードでは、まず`gets.chomp.split`で1行の入力を半角スペースで分割して、2つの数値になっているかを確認しています。また、数値に変換する前に正しいフォーマットかどうかもチェックしています。これにより、より確実なエラーハンドリングが行われます。
### 学び・感想
なるほど、`A`と`B`それぞれに代入するタイミングで数値に変換するのが今の自分には一番理解しやすい。
ちなみに、以下のような書き方もある。
```ruby:sample.rb
# 数値として入力を受け取る
numbers = gets.split.map(&:to_i)

A = numbers[0]
B = numbers[1]

D = A - B
P = A * B

puts "#{D} #{P}"
```
理屈が少し難しいので、一旦は`practice.rb`の書き方で進めようと思います。
【Tips】KVMにて、NICのパフォーマンスが悪くなる場合

# 結論

**KVMにて使用するNICを、`virtio`になっている事を確認する。**

仕事でKVMのVMを使用している時、監視ツールから、pingのロスを時々検出するという事例が発生した。その際に上記の方法を実行することでパフォーマンスが改善した。

https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/virtualization_administration_guide/sect-virtualization-troubleshooting-kvm_networking_performance

ちなみに、その時使用していたNICは`rtl8139`であった。

```
rtl8139 仮想化 NIC はほとんどの環境で問題なく機能しますが、
このデバイスは、10 ギガバイトイーサネットなど、一部のネットワークでパフォーマンス低下の問題が発生する可能性があります。
```

# 変更手順

### バックアップ取得＆シャットダウン
対象のゲストに入り、ネットワーク設定をコピペする。下記の例では一つだけだが、複数NICがあるときは都度コピーする。
```
cp -p /etc/sysconfig/network-scripts/ifcfg-eth0 /tmp/ifcfg-eth0.bk
```

その後、ゲストをシャットダウンする。
```
shutdown -h now
```

## ホストからの操作

ホストにSSHした後、以下のコマンドでゲストのxmlファイルを取得する。
```
sudo virsh dumpxml guest_vm_name >/tmp/guest_vm_name.xml
```

その後、virt-managerもしくはvirsh editで変更を行う。

### virt-managerの場合

以下コマンドを実行し、virt-managerを起動する。
```
sudo xauth add $(xauth -f ~/.Xauthority list | tail -1)
sudo virt-manager
```

virt-manager起動後、対象のゲストを選択し電球アイコンをクリックする。
NICの情報をクリックし、以下の画像のようにデバイスのモデルをvirt-ioへ変更し適用を押下する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1288524/d8c4f992-b4d7-9677-c96b-4d8a6ac4e786.png)

### virsh editの場合

以下のコマンドをホストにて実行する。
```
sudo virsh edit GUEST名
```
その後、interface-typeの部分に移動し、`model type`の部分を変える。
```:編集前
<interface type='network'>
  [output truncated]
  <model type='rtl8139' />
</interface>
```
```:編集後
<interface type='network'>
  [output truncated]
  <model type='virtio' />
</interface>
```
変更したら`wq`で保存する。

## ゲストの起動

以下のコマンドでゲストを起動させる。virt-managerで開いている場合はそこから起動させてもよい。
```
sudo virsh start GUEST名
```

以上。
HTMLをデバッグしてDOMがいつ更新されたかを追いかける

Google Chrome で HTML をデバッグできることを最近知った。開発者ツールの Elements を開いて右クリックで 「`Break on`」 という項目があるので、その中から Element の更新タイミングを選択するだけだ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59081/034dc447-d8bd-cff0-9fc5-00056244ebac.png)

- subtree modifications: 子要素に変更があったときに描画を一時停止する
- attribute modifications: 要素自体に変更があったときに描画を一時停止する
- node removal: 要素が消えたときに描画を一時停止する

自分の場合は、a タグに謎のクエリストリングが focus のタイミングの付与されるのを調べるときに役に立った。（そのときは GA の js が自動付与していたことがわかった。）
Rubyのeachとmapを比較してみた

## はじめに
転職をきっかけにRubyを触り始めており、プロダクションコードや書籍、チュートリアルで`each`と`map`が多用されいたのですが、メソッドの処理が似ているということもあり混乱してしまいました。

そこで、この二つのインスタンスメソッドの共通点や異なる点をリファレンスマニュアルを参考にしてまとめてみました。



## eachとmapの共通点
共通点は以下の二つです。
- Arrayクラスのインスタンスメソッドである
- ブロックを省略した場合は`Enumerator`が返る

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

Arrayのリファレンスマニュアルのインスタンスメソッドを確認すると、`each`と`map`があるのでどちらもArrayクラスのインスタンスメソッドであることがわかります。

また、`irb(interactive Ruby)`でブロックを省略した挙動を確認してみると`Enumerator`というものが返ってくることがわかります。

```ruby
irb(main):001> [1, 2, 3].each
=> #<Enumerator: ...>
irb(main):002> [1, 2, 3].map
=> #<Enumerator: ...>
```

### Enumeratorって何？
リファレンスには
> each 以外のメソッドにも Enumerable の機能を提供するためのラッパークラスです。また、外部イテレータとしても使えます。

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

とあります。
`Enumerable`は繰り返しを行うためのモジュールで、このモジュールをインクルードすることで`Enumerable`に定義されたインスタンスメソッドが使えるようになります。

`Enumerable`のリファレンスでは以下のように記述されています。
> 繰り返しを行なうクラスのための Mix-in。このモジュールのメソッドは全て each を用いて定義されているので、インクルードするクラスには each が定義されていなければなりません。

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

実際に`Enumerable`をインクルードしてみて確認します。
```ruby
irb(main):035* class MyClass
irb(main):036*   include Enumerable # <= Enumerableをインクルード
irb(main):037*   
irb(main):038*   def each; end
irb(main):039> end
=> :each
irb(main):040> MyClass.instance_methods # <= インスタンスメソッドを確認
=> 
[:each,
 :take_while,
 :drop,
 :drop_while,
 :cycle,
 :chunk,
 :slice_before,
 :slice_after,
 :slice_when,
 ...]
# ↑ Enumerableで定義されているインスタンスメソッドが列挙される
```

まとめると、`each`,`map`でブロックを省略した場合には、`Enumerable`という繰り返しを行うモジュールのラッパークラスである`Enumerator`クラスが返されるということですね。

また、`Enumerable`リファレンスの続きは以下のように記述されており、`map`もArrayクラスでオーバーライドされているメソッドの一つです。
>Array, Hash, Range, Enumerator等のクラスで、 Enumerableモジュールはインクルードされています。ただし、効率化のため、そのクラスでEnumerableと同名･同等の機能を再定義(オーバーライド)しているケースも少なくなく、特にArrayクラスでは同名のメソッドを再定義していることが多いです。

## eachとmapの相違点
相違点は以下の二つです。
- 処理内容
- 戻り値（ブロックが与えられた場合）

リファレンスを比較して確認してみます。

### each
> each -> {|item| ... } -> self
各要素に対してブロックを評価します。

https://docs.ruby-lang.org/ja/latest/class/Array.html#I_EACH

`each`はブロック内の処理を評価するのみで要素を加工した結果を返しません。`self（レシーバ自身）`を返します。

```ruby
[1, 2, 3, 4, 5].each { |i| i**2 } # <= ブロック内で要素の冪乗を返している
=> [1, 2, 3, 4, 5]                # <= 結果は変わらない

# object_idを確認してみる
arr = [1, 2, 3, 4, 5]
arr.object_id
=> 788540
new_arr = arr.each { |i| i**2 }
new_arr.object_id
=> 788540  # <= arrと同じ
```

### map
> map -> {|item| ... } -> [object]
各要素に対してブロックを評価した結果を全て含む配列を返します。

https://docs.ruby-lang.org/ja/latest/class/Array.html#I_COLLECT

`map`はブロック内の戻り値で新しい配列を作成して返します。

```ruby
[1, 2, 3, 4, 5].map { |i| i**2 } # <= ブロック内で要素の冪乗を返している
=> [1, 4, 9, 16, 25]

# object_idを確認してみる
arr = [1, 2, 3, 4, 5]
arr.object_id
=> 788540
new_arr = arr.map { |i| i**2 }
new_arr.object_id
=> 993360  # <= arrと異なる
```
Railsでのアーキテクチャを考える


### はじめに
Ruby on RailsでAPIの開発を行ってるんですが、Railsは開発者に優しくとても開発がしやすいです。一方、どこからでもModelが呼べたりと人によって書き方もバラバラになりやいフレームワークでもあります。
とはいえ、Rialsをクリーンアーキテクチャで設計して開発を進めていくのは、Railsの良さをなくしちゃうのであまり相性が良くないと思います。そこで、Railsの既存のMVCを崩さない範囲でルールを決めて開発を行うようにしました。
開発はRailsの6系で、APIモードで開発を行っています。


### 考えた各層の役割
最終的に各層の役割は以下のように定義しました。

|  | 役割、詳細 |
|---------|---------|
| Controller | パラメーターなどを取得し、Service層とPresenter層を呼び出す役割。ビジネスロジックは持たず、基本的に呼び出しのみを行う。 |
| Model  | バリデーションや（サービスではなく）ドメインに依存するロジックを持つ役割。joinやwhereなどactive recordを操作するようなものはscopeで定義し、それ以外のドメインに依存するロジックは関数で定義する。また、基本的にModel側は呼び出されることしかなく、呼び出し側に依存した処理は書かない。|
| Service   | 基本的にcontrollerから呼び出され、サービスにおけるビジネスロジックを持つ役割。また、テーブルの結合などもここで行う（結合のためのロジックはModelで持っても構わない）。 |
| Presenter   | APIにおけるjsonの返却値などを作成する役割。基本的に呼び出される役割でロジックなども持たないが、他のPresenter層やDecodater層、Model層で定義された関数（scopeは禁止。defで定義されたもののみ）を呼び出すことが可能。 |
| Decorater  | 表示部分のロジックを持つ役割。ビジネスロジックではない表示部分のロジックのみであれば、こちらで保持する。 |

呼び出しのイメージ
![スクリーンショット 2024-03-10 15.08.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218021/275f0142-2166-2df3-d77c-ea8c589669af.png)

### この方針にした時に特に考えたこと
 - ロジックをも持つ層を明確にしたかったので、ドメインに依存するロジック（Model層）、ビジネスロジック（Service層）、表示部分のロジック（Decorater層）に分けて定義しました
 - N+1問題を起こりにくいようにしたかったので、結合などは全てSerive層に閉じ込めました
 - Modelで定義する関数は、active recordを操作するものは`scope`で定義、それ以外にロジックだけ持つものは`def`で定義し、呼び出し側のルールも決めました。これにより上記のように結合場所をService層のみに閉じ込めやすくしました


### さいごに
ルールを決めるまでは結構書き方がバラバラになりやすかったのがルールを明確にすることで統一され、またN+1問題の解消にも繋がりました。
もちろんこれはあくまで自分たちのルールなので、正解とかありませんしサービスの規模感によっても変わると思いますがすこしでも参考になればと思います。
UiPath Automation Ops 編 ガバナンス デプロイ

## 初めに
今回はUipath AutomationOps ガバナンスで作成したポリシーを割り当てたいと思います。
まずはポリシーを作成しましょう。

<details><summary>Uipath Automation Ops 編 ガバナンス ポリシー</summary>

Assistantポリシー設定
https://qiita.com/npoif/items/0be7c4af46b291a7794c

Studioポリシー設定
https://qiita.com/npoif/items/f3d82757929ee19e314b

Robotポリシー設定
https://qiita.com/npoif/items/b8ece5e8f3ced4000c4c
</details>

**Uipath AutomationOps ガバナンス デプロイのドキュメントは下記を参照ください**

https://docs.uipath.com/ja/automation-ops/automation-suite/2023.10/user-guide/deploy-governance-policies-top

## デプロイ
### テナント
![スクリーンショット 2024-03-10 145100.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736921/a48ee40c-0037-3faf-4044-b06afeb538b4.png)

割り当て対象のライセンスを選択し、ポリシーを割り当て後に保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736921/8a4ed6d0-0608-2422-b13d-7d1f91d8a6cb.png)


## 関連記事
**Uipath Automation Ops 編 ガバナンス**

Assistantポリシー設定

https://qiita.com/npoif/items/0be7c4af46b291a7794c

Studioポリシー設定

https://qiita.com/npoif/items/f3d82757929ee19e314b

Robotポリシー設定

https://qiita.com/npoif/items/b8ece5e8f3ced4000c4c
Elixir: mix を使った加算

引数の扱いを確認するために加算のプログラムを作成しました。

## プロジェクトの作成

```bash
mix new sumup
cd sumup
```

lib/sumup.ex を改造

```exs:lib/sumup.ex
defmodule Sumup do
  @moduledoc """
  Documentation for `Sumup`.
  """

  @doc """
  Hello world.

  ## Examples

      iex> Sumup.hello()
      :world

  """
  def hello do
    :world
  end

  def main do
    IO.puts "*** 開始 ***"
    args = System.argv()
    IO.inspect(args)
    [aa, bb] = args
    IO.puts aa
    IO.puts bb
    sum = String.to_integer(aa) + String.to_integer(bb)
    IO.puts sum
    IO.puts "*** 終了 ***"
  end

end
```

## 実行

```bash
mix run -e Sumup.main 123 45
```

```text
$ mix run -e Sumup.main 123 45
*** 開始 ***
["123", "45"]
123
45
168
*** 終了 ***
```
画像にマスクをかける【道具としての OpenCV 画像認識】

# 本記事でできること
元画像
![fuji.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37698/e26e4d93-5b00-dced-2302-5df6267395d5.jpeg)


マスク画像
![mask.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37698/18b03ee0-20c3-429f-e4c0-4155a84da3c8.jpeg)


マスクをかけたあとの画像
![Screenshot from 2024-03-10 14-44-38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37698/7d5f726b-7873-7edb-2e33-bc6f7ba43968.png)


# 想定シーン
## ロボットをビジュアルフィードバック制御する
カメラを使ったロボットアームの制御方法を、ビジュアルフィードバック制御といいます。ここでは、ビジュアルフィードバック制御を使った自動化システムを開発する際に必要となる画像認識プログラムをまとめています。

## 画像にマスクをかける
カメラで撮影した画像には、対象物体の背景や、関係のない物体など、実際の画像認識には不要な部分が写り込んでいる場合があります。こうした不要な箇所を含めて画像処理フィルターをかけてしまうと想定したものと異なる結果が得られてしまい、ロボットのビジュアルフィードバック制御がうまくいかなくなる場合があります。そこで、カメラ画像に対して、見るべきもの以外を黒塗りしてしまう処理をマスク処理といいます。マスク処理では、見るべき箇所（＝ROI：Region of Interest）を定義して、それ以外を塗りつぶすマスク画像を作成して、元画像に対してマスク画像を重ねがけることで実装します。本記事では、マスク処理をするためのプログラムを掲載します。

# 実行環境
- OS：Ubuntu 22.04 LTS
- 言語：C++
- クルーボ：v5.1.0

## クルーボについて
ロボットアプリケーション開発には、株式会社チトセロボティクスのロボット制御ソフトウェア「クルーボ」を使用します。本記事のプログラムは、クルーボがインストールされた制御コンピュータ上で動作します。

- クルーボの製品サイト：https://chitose-robotics.com/

## プログラム抜粋
```c++
cv::Mat set_mask_on_image(const cv::Mat& target_image, const cv::Mat& mask_image) {
    cv::Mat masked_image;
    if (target_image.channels() == 1) {
        cv::Mat mask_image_gray = convert_grayscale(mask_image);
        target_image.copyTo(masked_image, mask_image_gray);
    } else {
        target_image.copyTo(masked_image, mask_image);
    }
    return masked_image;
}
```

## 全体プログラム
```c++
#include <iostream>
#include <opencv2/opencv.hpp>

cv::Mat load_image(const std::string file_path) {
    cv::Mat loaded_image = cv::imread(file_path, 1);
    if (loaded_image.empty()) {
        throw std::runtime_error("画像を正常に読み込めませんでした。");
    }
    return loaded_image;
}

cv::Mat convert_grayscale(const cv::Mat& image) {
    const int grayscale_channel_num = 1;
    if (image.channels() == grayscale_channel_num) {
        return image.clone();
    }
    cv::Mat gray_image;
    cvtColor(image, gray_image, cv::COLOR_BGR2GRAY);
    return gray_image;
}

cv::Mat set_mask_on_image(const cv::Mat& target_image, const cv::Mat& mask_image) {
    cv::Mat masked_image;
    if (target_image.channels() == 1) {
        cv::Mat mask_image_gray = convert_grayscale(mask_image);
        target_image.copyTo(masked_image, mask_image_gray);
    } else {
        target_image.copyTo(masked_image, mask_image);
    }
    return masked_image;
}

int main(void) {
    std::string file_path = "../data/fuji.jpg";
    const cv::Mat loaded_image = load_image(file_path);
    std::string file_path_mask = "../data/mask.jpg";
    const cv::Mat mask_image = load_image(file_path_mask);

    const cv::Mat masked_image = set_mask_on_image(loaded_image, mask_image);

    cv::imshow("masked_image", masked_image);
    cv::waitKey(0);
}
```

## おわりに
人手作業をロボットアームで自動化するために、カメラを使ったロボット制御＝ビジュアルフィードバック制御が大切です。
ロボット制御用の画像認識でも中身のひとつひとつはシンプルなので、要素に分解して解説していきたいと思います。
2024/03/01くらいのVSCodeアップデート以降C++拡張のIntelliSenseの調子が悪い件について

# 現象
2024年3月の頭ごろVSCodeにアップデートがありました。それ以降、C++拡張のIntelliSenseの調子が悪いという現象が起きていました。~~勝手に改悪するのやめてくれないかな~~

具体的には、私の環境では、最初は普通に動くのですが、しばらく作業してるとIntelliSenseが効かなくなる(変数の色分けがされなくなる・エディタ上で検出されたコンパイルエラーがコードを書き換えても更新されない)という症状が出ました。さらに、この状態でセーブしようとするとformatOnSaveで走るformat処理が無限に終わらず、formatをキャンセルしなければセーブもできない状態になってしまっていました。

これらの症状はwindowを開きなおすと解消していましたが、数分後には再現してしまいとても作業に支障をきたしていました。

まったく同様の症状かは不明ですが、X上での競プロのコミュニティではIntelliSenseの不調を感じている人が私以外にも複数存在します。

# 環境
何が影響しているのかわからないので大きなところだけ書きます。
VSCode : version 1.87.1
C/C++拡張 : version 1.19.6

マシンのosはwindows11ですが、WSL2でUbuntuの仮想環境を作ってそこにVSCodeでリモート接続しています。

`c_cpp_properties.json`の内容を載せておきます。競プロ用のライブラリが`includePath`に含まれている以外は普通の環境だと思われます。このライブラリも大したサイズではありません。
```json
{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/*",
                "/hoge/proCon/acl"
            ],
            "defines": [
                "LOCAL",
                "DEBUG"
            ],
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "gnu17",
            "cppStandard": "gnu++23",
            "intelliSenseMode": "linux-gcc-x64"
        }
    ],
    "version": 4
}
```

# 解消した？
結論として、私の環境ではC/C++拡張のversionを`1.19.6`から`1.18.5`にダウングレードすることで上記の症状は出なくなりました。X上でも改善したという声があるので、困っている方は試してみたらいいかもしれません。

このissueを参考にしました。

https://github.com/microsoft/vscode-cpptools/issues/12017

# 最後に
間に合わせの対策に過ぎないので、あんまり信用しないでください...
この件についてなにか根本的な原因をご存じの方いたら教えてほしいです。
CloudFront継続的デプロイでは変更できない機能について

# はじめに
`CloudFront`継続的デプロイの機能を使っていたところ、継続的デプロイで作成したステージング`CloudFront`を削除・昇格させないと変更できない設定がありました。

`AWS`のドキュメントも調べてみましたが、それらしいドキュメントは見つからなかったので、記事に残しておこうと思います。

- 【以前の記事】[CloudFront構成でもECSブルーグリーンデプロイメントを使えるようにする。](https://qiita.com/sakai00kou/items/13c93080467fb91b7eec)

# CloudFront継続的デプロイでは変更できない機能
`CloudFront`継続的デプロイ機能でステージング`CloudFront`が作成されている状態では設定がグレーアウトされて、変更できない機能を以下にまとめます。

|変更できない機能|備考|
|:--|:--|
|料金クラス|料金区分の設定|
|カスタムSSL証明書|別のSSL証明書に入れ替える際に指定|
|サポートされているHTTPバージョン|サポートするHTTPバージョンの指定|
|IPv6|IPv6サポートのオン/オフの設定|
|WAF|AWS WAFの有効/無効化設定|

上記の設定を変更する場合は前述の通り、ステージング`CloudFront`が存在すると設定できないので削除か昇格させて本番用`CloudFront`のみの状態にしてから設定変更を行いましょう。

# おわりに
以前紹介したような構成でシステムを運用している場合、ステージング構成を作成したままにしている方もいるかと思います。

私の場合、`CloudFront`のSSL証明書を入れ替えようとした際に判明したので、ステージング`CloudFront`の削除→SSL証明書入れ替え→ステージング`CloudFront`再作成を行いました。

基本的にはビヘイビアやキャッシュポリシー等を入れ替える際にステージング`CloudFront`を作成して動作確認を行い、終わったら昇格させるような使い方が想定されている使用方法かと思いますが、私のような使い方をしている方は参考にして頂ければと思います。
CpawCTF Q21.[Reversing]reversing easy!

# CpawCTF Q21.[Reversing]reversing easy!
```terminal:binary.tr
$file rev100
rev100: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=f94360edd84a940de2b74007d4289705601d618d, not stripped
$strings rev100
....
D$Fcpawf
D$J{
D$ y
D$$a
D$(k
D$,i
D$0n
D$4i
D$8k
D$<u
D$@!
....
```
ここにあるcpaw{yakiniku!}が答え
![スクリーンショット 2024-02-16 171004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3685661/bd13dd94-0ba8-7230-a30f-d69bbf33e2af.png)
バイナリーエディタで解析するとこの部分にある。
配列の生成・初期化コストを低減するテクニック

# 概要
本記事では、プログラミング言語で配列の生成・初期化コストを低減する方法について説明します。言語はJavaで説明しますが、他の言語でも考え方は通用すると思います。
タイトル詐欺的なところがあるかもしれないので予めお断りしておきますと、基本的には一度作った配列を使い回すという至極当たり前な方法なのですが、使い回す際の工夫によって、初期値を配列全体に設定するコストを低減することができる、という内容になります。

# モチベーション
競技プログラミングなどで最短経路問題を解く時に、ダイクストラ法や01BFS等を使うために各頂点までの距離を保持する用の配列を用意することがあると思います。以下のようなコードで`dist`に当たる変数です。

```Java
int[] dist = new int[N];
Arrays.fill(dist, Integer.MAX_VALUE);
dist[0] = 0;
ArrayDeque<Integer> queue = new ArrayDeque<>();
queue.add(0);
while ( queue.size() > 0 ) {
   // 省略
}
```

$N$が頂点数ですが、配列`dist`の生成と初期値(ここでは`Integer.MAX_VALUE`)を代入するのに$O(N)$の計算量がかかります。ただしこの場合は、全体の計算量がダイクストラだったら$O(M + N\log N)$、01BFSなら$O(M + N)$かかるので、配列の初期化は特にボトルネックになるようなものではありません。

ところが、ヒューリスティックコンテスト等では、探索する盤面全体としてはそれなりの広さがあるものの距離や経路を求めたい箇所はその中の一部の領域だけで、配列の生成・初期化の部分がボトルネックになってしまうというケースがあります。
例として、先日行われた[第一回マスターズ選手権予選](https://atcoder.jp/contests/masters-qual/tasks/masters_qual_a)で、[北村氏による解法](https://medium.com/karakuri/第一回マスターズ予選-参加記-8f605012aa4a)では、現在地から最も近い「配置条件を満たしていないマス」およびそこまでの経路を求める必要が出てきます。盤面全体の広さとしては$N\times N$ですが、「配置条件を満たしていないマス」はすぐ近くにあることが期待できるので、毎回`dist`に当たる変数の初期化を行うと、そこがボトルネックになってしまいます。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202945/d72b3f47-e56a-e730-9bec-efeea9093fbe.png">

本記事では、このような状況で初期化を$O(1)$で実行するテクニックについて説明します。

もちろん、連想配列(Javaでは`HashMap`)を使うことで解決する方法もありますが、Javaの場合だとオートボクシングが発生してパフォーマンスが劣化しがちなので、別の方法を考えてみました。

# 解決方法
以下のアプローチです。

- 値を保持する配列に加えて、世代番号を保持する配列を持つ。現在世代番号も管理する。
- 値を設定する場合は、値を保持する配列の更新に加えて、世代番号の配列も現在世代番号に更新する。
- 値を取得する場合は、世代番号が現在世代番号であれば値そのものを返し、違う場合は初期値を返す。
- 初期化を行う場合は、現在世代番号を1つ進める。

ソースコードにすると以下のようになります。

```Java
class MyArray {
  int N = 0; // 配列サイズ
  int[] val = null; // 値を保持する配列
  int[] gen = null; // 世代番号を保持する配列
  int curGen = 1; // 現在世代番号
  int defaultVal = 0; // 初期値
  MyArray(int N, int defaultVal) {
    this.N = N;
    this.val = new int[N];
    this.gen = new int[N];
    this.defaultVal = defaultVal;
  }
  // 初期化
  void clear() {
    curGen++; // 現在世代番号をインクリメント
  }
  // 値の取得
  int get(int i) {
    return gen[i] == curGen ? val[i] : defaultVal; // 世代番号が一致しない場合は初期値を返却
  }
  // 値の設定
  void set(int i, int v) {
    gen[i] = curGen; // 現在世代番号を設定
    val[i] = v;
  }
}
```

`clear()`を実行しても`val`の中身はそのままですが、現在世代番号をインクリメントすることで$O(1)$で実質的に各要素を初期値扱いにしています。メリットはもちろん初期化が配列の長さに依存せずに実行できることですが、デメリットもあります。

- 値の設定時に2つの配列を更新する分パフォーマンスが落ちる
- 値の取得時に条件分岐が発生する分パフォーマンスが落ちる

したがって、「モチベーション」の項で述べたように、配列の一部だけを使って処理を行うような場合は高速化が図れますが、配列全体を使うようなケースの場合はかえって劣化することになります。

# おわりに
競技プログラミングでもアルゴリズム系のコンテストでこのテクニックを使うことはほぼないと思いますが、ヒューリスティックコンテストでは全体の一部だけしか使わない判定を繰り返し実施することがあるので、これまでのコンテストで筆者は何度かこのテクニックを使用しています。
もっと良いやり方があるのか理由は不明ですが、あまりネット上で見かけないテクニックだったので、今回記事にしてみました。何かの参考になれば幸いです。

〜追記〜
Xで情報をいただきましたが、昔、コンピュータ将棋で置換表を初期化するのにもこの手法が使用されていたそうで「論理初期化」と呼ばれていたそうです。

(さらに追記)
追加情報をいただきました。PsyhoさんによるヒューリスティックコンテストのTips集によると、この手法は"Fast-Clearing Array"と呼ばれているようです。

- [Psyhoさんによるヒューリスティック・ボットコンテストのための無料Tips](https://ozy4dm.hateblo.jp/entry/2022/12/22/162046) (Tipsを翻訳された方の記事。#63,64参照)

また、上記記事からリンクされていますが、tomerunさんの記事でもこの手法の紹介がありました。こちらでは固有の名称では呼ばれておらず、以下記事タイトルの通りとなっています。

- [BFSを繰り返すときに訪問済みかを記録する配列を毎回初期化しなくて良くするアレ](https://topcoder-tomerun.hatenablog.jp/entry/2022/11/06/145156)
querySelectorの返り値の型を絞り込む関数を作る

# 背景
querySelector(),querySelectorAll()で型が```Element```,```NodeListOf<Element>```になって毎回型チェックをするのが手間だなと感じていました。

# querySelectorの返り値の型を絞り込む関数

```ts
const safeQuerySelector = <T extends Element>(
  root: Element | Document,
  selector: string,
  expectedElementType: { new (): T; prototype: T }
): T | null => {
  const elm = root.querySelector(selector);
  if (elm instanceof expectedElementType) return elm;
  return null;
};

const a = safeQuerySelector(document, "div", HTMLDivElement); //HTMLDivElement|null
```

# 今後の課題
第二引数のselectorの文字列がセレクタの構文として問題があるときにnever型で返すようにしたいです。

https://qiita.com/yamatai12/items/59c7066775e20beefb95

以前調べた typed-query-selector のstrictモードのようなものです。

# 最後に
- ジェネリクスを使いこなせるようになりたいです!
- typed-query-selectorのソースが勉強になるので眺めようと思います
- あとはブルーベリー本も読みたいです
Discord.jsでプログラムがエラーを吐いても起動させ続ける

# 前置きの前置き
何と
```js
process.on('uncaughtException', err => console.log(err))
```
**このコードをどこかに書いておけば大丈夫だそうです**
(つまりこれはただのライブラリ紹介)
# 前置き
多分初投稿のumisoraです
PCの起動時に.batでbotも起動できるかなーとか思いながら調べていましたら
pm2というライブラリを見つけたので忘備録 + 紹介です...！
# 仕組み(ざっくりと)
どうやらエラーを吐いたプロセスをもう一度起動する仕組みのようです
もっと詳しく知りたい方は調べてみるといいかもしれません
# 結局どうやるの？
やり方はいたって簡単
まずはnpmでpm2をインストールします
```bash
npm install pm2 -g
```
そしたら皆さんいろんなランタイムを使ってるかもしれませんが起動コマンドを
```cmd
pm2 start [botが起動するファイル名(拡張子省略不可)]
```
とします(一応cdかなんか使ってbotが起動するファイルのあるディレクトリで実行してください)
筆者の場合は
```bash
pm2 start index.js
```
となります
するとコンソールに
```cmd
[PM2] Applying action restartProcessId on app [index](ids: [ 0 ])
[PM2] [index](0) ✓
[PM2] Process successfully started
┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐
│ id │ name               │ mode     │ ↺    │ status    │ cpu      │ memory   │
├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤
│ 0  │ index              │ fork     │ 0    │ online    │ 0%       │ 51.3mb   │
└────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘

```
こんな感じで表示されます
statusがonlineになっていれば起動しています
botを停止する際は
```cmd
pm2 stop [botが起動するファイル名(拡張子省略不可)]
```
と打ちます
するとコンソールに
```cmd
[PM2] Applying action stopProcessId on app [index.js](ids: [ 0 ])
[PM2] [index](0) ✓
┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐
│ id │ name               │ mode     │ ↺    │ status    │ cpu      │ memory   │
├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤
│ 0  │ index              │ fork     │ 0    │ stopped   │ 0%       │ 0b       │
└────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘
```
こんな感じで停止したのがわかります(status欄にstoppedと書かれていれば停止しています)
試しにエラーを吐かせてみましょう(Discord.js v14で実験します)
botのmessageCreateイベント内に
```js index.js
client.on(Events.MessageCreate, async (message) => {
    if (message.content == "err") message.channel.send("") //errというメッセージが送られたら空のメッセージを送る(つまりエラーを吐かせる)
}
```
こんなプログラムを追加してそのbotが参加しているサーバーでerrというメッセージを送信してみましょう
普通ならばCannot send empty messageなどと出るはずですが、コンソールを見ると何も表示されず、何もなかったかのように動き続けています(さっき追加した一文は消しておきましょう)
pm2でbotを運用する時のデメリットとしては
・エラーが出ないのでエラーが出た原因がわからない
・まずエラーが出たのかどうかもわからない
なのでエラーを確認したい場合はいつも通りnodeやyarnやbunなどで起動するのが好ましいでしょう

# 終わり
気が向いたらDiscord.jsの記事やNextの記事なども書く予定です...
読んでくださりありがとうございました...！

# 参考
前置きの前置き

https://twitter.com/KelpOfTruth

ライブラリ紹介

https://tech-browse.com/programming/nodejs/nodejs-avoid-stopping-web-server-down/

https://teratail.com/questions/148985
無料の『ONES Wiki』で情報・ナレッジのスペースを作成する

# はじめに
自分の性格上、なかなか覚えられない性格なので、やったことをONES Wikiに記録しています。
「あれをやる時は、最初に何やるんだっけ？」と思った時に、ONES Wikiを検索することで、ものすごく助かっています。Free版なのに、ここまでの機能があるナレッジ管理ツールは、あまり見かけないですね。

# ナレッジ管理ツール ONES Wikiってなに？
ONES Wikiは、シンガポールに本社を置く会社が開発する製品です。2024年2月頃にライセンス体系が変更され、Free版がリリースされました。5ユーザーまでは無料で使うことができます。

# なぜONES Wikiなのか？
お金をかけたくないので、すでに利用しているMicrosoft365に含まれているSharePointや10ユーザーまで無料で使えるアトラシアン社のConfluence（コンフルエンス）で、なんとか頑張って使おうとしたのです。でもダメでした。断念した理由は以下です。

#### SharePointの場合
そもそもナレッジ管理というよりも、掲示板的な使い方を想定している製品だと感じました。情報の登録も「ニュース投稿」という表現ですし、テンプレートもWEBポータル的にデザインのようなのでナレッジ管理としてSharePointを使ってしまうと、お金はかからないですが、生産性が低下してしまう可能性が高い。つまりコストはかからないですが、マイナスの効果を生み出すことになってしまう。

#### Confluence（コンフルエンス）の場合
アトラシアン社のConfluenceは10ユーザーまで無料利用できるFreeプランを提供しています。外部業者との情報共有として利用しているのですが、過去記事にも書きましたが、いくつか制限があります。

過去の記事：[無料で使える最強のナレッジ管理ツールを発見！](https://qiita.com/sunfish/items/ac601d87233f16018a6b)

機能的にはよかったのですが、ストレージ容量の制限とアクセス制御、それと日本語が問題でした。
これだと周りからガヤガヤ言われそうな気がしたので面倒なことが起きないように断念しました。
 - ストレージ容量が2GBまでなので、気がついたら容量が限界になって「はい終了！」にはなりたくない。
 - 登録ユーザーにすべての情報が公開されてしまうので、これは厳しいですね。
 - 日本語で利用するには、日本語フォントをインストールしたりなど、製品を詳しくしらないと設定で問題が起きそうですし、製品を勉強する時間もありませんでした
 - スペースの階層表示ができなかった。これだと情報がみつけにくい。

## やってみよう！ ONES Wikiでスペースを作成する
ONES Wikiで情報ページを登録するためのスペースを作成してみます。

#### スペース作成の権限
スペース作成権限をもつユーザーがスペースを作成することができます。
権限の付与は、「設定センター」ー「ナレッジベース管理設定」ー「権限設定」から行えます。
![スクリーンショット 2024-03-10 10.49.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192823/fa435bad-eb5a-0a67-84f5-b2bdf63364bd.png)

#### スペースを作成
「＋スペースを作成」をクリックします。
![qiita_oneswiki1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192823/64ba74df-4a4f-3cc4-6c27-26ff95a19583.png)

スペースを作成するには、以下の情報を入力します。
 - スペース名（必須）
 - カテゴリー（任意）
 - 内部共有の有効化

![qiita_oneswiki3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192823/cb0a78cd-6ea8-8b49-4148-9f5fcac2271b.png)

スペース作成で重要なのは、カテゴリーの設定です。

スペース作成時にカテゴリを選択しなかった場合は、「すべてのカテゴリー」のみにスペースが表示されます。カテゴリーを設定すると、「すべてのカテゴリー」と「選択したカテゴリー」にスペースが表示されます。

ここは難しく考える必要はありません。図のように組織単位でカテゴリーを作成したり、業務単位、プロジェクト単位、用途単位でカテゴリーを作成すると使いやすくなります。
![qiita_oneswiki4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192823/b1323fa2-3f2a-3cc3-4794-a839e571b0c2.png)

「内部共有の有効化」をONにするとページに「共有」が利用でき、OFFにすると利用できません。
![qiita_oneswiki5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192823/fd7ae0a5-19ef-3eee-98de-35c37113a789.png)

ここまで入力したら「確定」をクリックするとスペースが作成され、下図のような画面になります。

![qiita_oneswiki6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192823/52abb275-f1ad-9120-1808-d07f1c170019.png)

## どんどん情報やナレッジを登録してください。
これでスペースを作成できました。自由に情報・ナレッジを作成してください。
CloudFormation について学んだことをアウトプット

初めまして、目黒です。

4月からAWSの仕事に携わるために、AWSの資格を取得するため日々勉強をしています。
現在は3月末の SOAの試験に向けて勉強中です。

今回は、「CloudFormation」についての学習をまとめます。

## CFnの特徴
コードでサービスを管理できる点（IaC）。

コードにて環境構築をすることは、手作業で環境構築をするよりも下記の点で優れています。
* 再現性
* 時間効率

## CFnの説明
スタックという単位で環境を作成・更新・削除を行えます。

以下の３ステップでスタックに環境を構築します。

１．テンプレ
　　様々な要素で構成されている
　　※Resources のみ必須
２．CloudFormation がテンプレートを読み込む
　　スタックの作成/更新/削除 エラー検知 ロールバック
３．スタック
　　スタックという単位でテンプレに記載されているサービスを立ち上げる

## 実施したハンズオン
１．[AWS Hands-on for Beginners
AWS 環境のコード管理 AWS CloudFormationで Web システムを構築する](https://pages.awscloud.com/JAPAN-event-OE-Hands-on-for-Beginners-cfn-2022-reg-event.html?trk=aws_introduction_page)

## 類似サービスとの違い
* OpsWorks

# 自己紹介
初めまして、目黒です。(@megggguguuuuuuu)

高専を卒業後、新卒で今の会社に入社をしました。
今年の4月で、3年目突入になります。

現在は、SESにてとあるサービスの運用・保守をしています。
4月以降はAWS関連のメインの業務に参画する予定なため、AWSの勉強を行っております。

AWS資格を現在 CLF,SAA を取得しており、現在 SOA の資格取得に向けて勉強中。
DVA は6月までに取得するつもります。

AWS資格 12冠することが目標です。
同じくAWS 資格を目指す方は、お互いに刺激しあいながら資格取得に向けて頑張りましょう！

# 宣伝
毎週の土日に、僕が入社している会社のオフィス(池袋)にて「もくもく会」をしています。
ぜひご興味がある方がいましたらご参加ください！！！

https://mokumoku-teikoku.connpass.com/
AtCoder Beginner Contest 338 振り返り

# ABC338
## 概要
https://atcoder.jp/contests/abc338

## A - Capitalized?
__考えてたこと__
少し悩みましたが、一文字目だけ取ってきてisUpper, 残りをisLowerで判別。

__提出したもの__
```c++:a.cpp
int main() {
    string s;
    cin >> s;
    bool ans = isupper(s[0]);
    for (int i = 1; i < s.size(); i++) {
        if (!(islower(s[i]))) {
            ans = false;
        }
    }
    if (ans) {
        cout << "Yes" << endl;
    } else {
        cout << "No" << endl;
    }
    return 0;
}
```

__振り返り__
他にも大文字 -> 小文字の順に辞書順で並ぶからそれを活かして...とかも考えたけど上のやり方が一番楽そう?

## B - Frequency
__考えてたこと__
アルファベット26文字で入力1000文字だから気合いでなんとかなる、あとはアルファベット順を早いものを出力するように注意するだけ。

__提出したもの__
```c++:b.cpp
int main() {
    string s;
    cin >> s;
    char ans;
    int ans_max = 0;
    map<char, int> cnt;
    fore(a, s) {
        if (cnt.count(a)) {
            cnt[a]++;
        } else {
            cnt[a] = 1;
        }
        if (ans_max < cnt[a]) {
            ans_max = cnt[a];
            ans = a;
        } else if (ans_max == cnt[a] && a < ans) {
            ans = a;
        }
    }
    cout << ans << endl;
    return 0;
}
```
__振り返り__
これが一番簡単そう。

## C - Leftover Recipes
__考えてたこと__
A,Bのそれぞれの人数を全探索してたら間に合わないだろうなぁ...最大だから片方全探索してもう片方の最大値だけ常に求めれば良いかなぁ...と考えたら大体そんな感じだった問題。

__提出したもの__
```c++:c.cpp
int main() {
    ll n;
    cin >> n;
    vector<ll> vec_q, vec_a, vec_b;
    rep(i, 0, n) {
        ll q;
        cin >> q;
        vec_q.push_back(q);
    }
    rep(i, 0, n) {
        ll a;
        cin >> a;
        vec_a.push_back(a);
    }
    rep(i, 0, n) {
        ll b;
        cin >> b;
        vec_b.push_back(b);
    }

    // 作った人数分の料理
    ll ans = 0;
    ll a_max;
    ll b_max = 100100100;

    // Aの人数を回すfor文
    for (ll i = 0; i <= 1000000; i++) {
        a_max = i;
        // 材料を回すfor文
        for (ll j = 0; j < n; j++) {
            if (vec_q[j] >= vec_a[j] * i) {
                if (vec_b[j] != 0) {
                    b_max = min((vec_q[j] - vec_a[j] * i) / vec_b[j], b_max);
                }
            } else {
                break;
            }
            if (j == n - 1) {
                ans = max(ans, a_max + b_max);
            }
        }
    }
    cout << ans << endl;
    return 0;
}
```

__振り返り__
料理の必要グラムが0のパターンがあることに気づいてなかったことと、気づいた上でそれを処理に入れるのに結構苦戦した。

## 感想
Dが水色...またの機会に解きます。一旦は緑までは解説読んで解くことを目標に。
Next.jsのデプロイでTypeError: Cannot destructure property 'customConfig'エラーが出る

# はじめに

Next.jsでエラーが発生して突然デプロイできなくなり、ネットに情報がまったくなかったのでまとめていきます

# 問題

Firebaseにデプロイすると以下のエラーが出ました
ローカルではうまく動いています

```
[debug] [2024-03-10T04:25:11.395Z] TypeError: Cannot destructure property 'customConfig' of '(intermediate value)(intermediate value)(intermediate value)' as it is null.
    at loadConfig (/home/watanabejin/workspace/myblog/node_modules/next/dist/server/config.js:646:41)
    at getConfig (/usr/local/lib/node_modules/firebase-tools/lib/frameworks/next/index.js:390:28)
    at build (/usr/local/lib/node_modules/firebase-tools/lib/frameworks/next/index.js:67:65)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async prepareFrameworks (/usr/local/lib/node_modules/firebase-tools/lib/frameworks/index.js:216:33)
    at async deploy (/usr/local/lib/node_modules/firebase-tools/lib/deploy/index.js:55:13)
```

# 解決方法

`next.config.js`に問題が有りました

```js:next.config.js
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "qiita-user-contents.imgix.net",
      },
      {
        protocol: "https",
        hostname: "images.microcms-assets.io",
      },
    ],
  },
  reactStrictMode: false,
};
```

これを`next.config.mjs`にして以下のように書くことでうまく生きました

```js:next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "images.microcms-assets.io",
      },
    ],
  },
  reactStrictMode: false,
};

export default nextConfig;
```

# おわりに

なんとか原因がわかってよかったです。あまりネットに情報がないエラーを解決すると嬉しいです
【Aurora】各エンドポイントの違い

# 概要
Auroraの勉強をしている中でエンドポイントがいくつか出てきた。
各々のエンドポイントの違いを整理してみます。

# Auroraの概要・特徴
- AWSが構築したクラウド向けデーターベース
- 1つ以上のDBインスタンスと、データを管理するクラスターで構成される
- データを3つのAZに2個ずつ、合計6個のコピーを作成するため、高い耐障害性を持つ
- 読み込み専用のリードレプリカを最大15個作成できる。プライマリインスタンスに障害があった場合、レプリカがプライマリに昇格してフェイルオーバーする


![Auroraの概要.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1382306/0540e07e-fd9d-81cd-576a-131ded64d1cf.png)


# エンドポイントの種類
Auroraで使用できるエンドポイントは以下の4種類。
- クラスターエンドポイント
- リーダーエンドポイント
- カスタムエンドポイント
- インスタンスエンドポイント

# クラスターエンドポイント
DBクラスターの現在のプライマリDBインスタンスに接続するためのエンドポイントで、唯一書き込み処理を実行できる。
![クラスターエンドポイント.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1382306/1c08ba48-4327-b26c-0deb-0d1fb7639df9.png)

クラスターエンドポイントは読み取り書き込み接続のフェイルオーバーをサポートしていて、プライマリインスタンスへの接続に失敗した場合は、新しいプライマリインスタンスに自動的にフェイルオーバーする。

# リーダーエンドポイント
DBクラスターのRead Replicaのいずれかのインスタンスへ接続するためのエンドポイント。1つ以上のレプリカがある場合、レプリカ間で各接続リクエストを負荷分散する。

![リーダーエンドポイント.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1382306/65105709-4ed8-bfc2-deb0-7522cf2716e7.png)

# カスタムエンドポイント
特定のDBインスタンスのグループを作成し、そのグループ内のいずれかのインスタンスへ接続するためのエンドポイント。特定のインスタンスは分析用に使用するといった特殊なワークロードで活用する。
![カスタムエンドポイント.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1382306/1a612830-8dbf-5b5d-0b91-a1eee3cc4bb5.png)

# インスタンスエンドポイント
クラスター内の特定のDBインスタンスへ接続するためのエンドポイント。負荷分散はしない。
![インスタンスエンドポイント.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1382306/a287d6fa-ea28-f572-4106-11e6e82e2a0d.png)


# まとめ
#### クラスターエンドポイント
DBクラスターの現在のプライマリインスタンスに接続する。書き込みオペレーションを実行できる唯一のエンドポイント
#### リーダーエンドポイント
DBクラスターへの読み込み専用接続を負荷分散する。最大15個のレプリカを作成でき、レプリカから読み込む
#### カスタムエンドポイント
特定のDBインスタンスのグループに接続する。グループ内のいずれかのインスタンスを選択し接続処理を行う
#### インスタンスエンドポイント
クラスター内の特定のDBインスタンスに接続する。

# 参考
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/Aurora.Overview.Endpoints.html