OmniAICreator/Qiita-1.07M huggingface dataset:
スクリーンショット（画面キャプチャ）を保存するVBAコード

```vb:ScreenShotModule.bas
Option Explicit

Public Declare PtrSafe Sub keybd_event Lib "user32" (ByVal bVk As Byte, _
                                                    ByVal bScan As Byte, _
                                                    ByVal dwFlags As Long, _
                                                    ByVal dwExtraInfo As Long)

Const ALT_KEY = &HA4            '//［Alt］キー
Const PRINT_SCRN_KEY = &H2C     '//［PrintScrn］キー
Const KEY_DOWN = &H1            '// キーを押す
Const KEY_UP = &H2              '// キーを放す
```
```vb:
'// クリップボードの画像を保存する

Sub SaveScreenShot(ByVal save_folder_path As String, _
                    ByVal img_file_name As String, _
                    ByVal img_type As String, _
                    Optional ByVal alt As Boolean)

'    save_folder_path［画像の保存先フォルダパス］（例：C:\temp\Images）
'    img_file_name   ［画像のファイル名］        （例：hoge.png）
'    img_type        ［画像フォーマット］        （png、jpg、bmpなど）
'    alt             ［Altキーを押すかどうか］   （アクティブウィンドウのみキャプチャするかどうか）

    Dim psCmdStr    As String   '// PowerShellコマンド
    Dim imgFilePath As String   '// 画像のフルパス

    imgFilePath = CreateObject("Scripting.FileSystemObject").BuildPath(save_folder_path, img_file_name)

    '//［Alt］キーを押す（アクティブウィンドウをキャプチャする場合）
    If alt Then keybd_event ALT_KEY, 0, KEY_DOWN, 0

    '//［PrintScrn］キーを押す
    keybd_event PRINT_SCRN_KEY, 0, KEY_DOWN, 0

    '//［PrintScrn］キーを放す
    keybd_event PRINT_SCRN_KEY, 0, KEY_DOWN Or KEY_UP, 0

    '//［Alt］キーを放す（アクティブウィンドウをキャプチャする場合）
    If alt Then keybd_event ALT_KEY, 0, KEY_DOWN Or KEY_UP, 0

    '// PowerShellのクリップボード画像保存コマンド
    psCmdStr = "powershell Add-Type -AssemblyName System.Windows.Forms;$ImagePath = '" & imgFilePath & _
               "';  [Windows.Forms.Clipboard]::GetImage().Save($ImagePath, [System.Drawing.Imaging.ImageFormat]::" & _
               img_type & ")"

    '// PowerShellコマンド実行
    CreateObject("WScript.Shell").Run Command:=psCmdStr, WindowStyle:=0, WaitOnReturn:=True

End Sub
```
```vb:
Sub test1()

    Dim saveFolderPath  As String
    Dim imgFileName     As String
    Dim imgType         As String

    saveFolderPath = CreateObject("WScript.Shell").ExpandEnvironmentStrings("%USERPROFILE%") & "\Downloads"
    imgFileName = "hoge.png"
    imgType = "png"

    Call SaveScreenShot(saveFolderPath, imgFileName, imgType, True)

End Sub
```
参照サイト：
[Excel VBA を学ぶなら moug モーグ | 即効テクニック | 画面をキャプチャする](https://www.moug.net/tech/exvba/0150121.html)
[Excelマクロでスクショを取る - 技術関連の覚書](https://boctoc1969.hatenablog.com/entry/2020/07/11/115011)
[クリップボードの画像を保存する方法！マクロで簡単実装！ - エク短｜Extan.jp](https://extan.jp/?p=10114)
リッジ回帰の双対表現

## リッジ回帰の双対表現

PRML Chapter6 p.3参照

```math
\begin {align*}
& J(\mathbf{w}) = \frac{1}{2} \sum\left(y_i - \mathbf{x}_i^T\mathbf{w}\right)^2+\frac{1}{2} \lambda \mathbf{w}^T\mathbf{w} \\
& \frac{\partial}{\partial \mathbf{w}}=0 \\
& \mathbf{w}=\frac{1}{\lambda}\sum\left(y_i - \mathbf{x}_i^T\mathbf{w}\right)\mathbf{x}_i \\
& \mathbf{w}=\sum a_i \mathbf{x}_i \\
& (a_i = \frac{1}{\lambda}\left(y_i - \mathbf{x}_i^T\mathbf{w}\right)) \\
& \mathbf{w} = \left(\mathbf{x}_1, \ldots, \mathbf{x}_N\right)\left(\begin{array}{c}
a_1 \\
\vdots \\
a_N
\end{array}\right) \\
& \mathbf{w} = \mathbf{X}^T\mathbf{a} \\
\end {align*}
```  

```math
\begin {align*}
J(\mathbf{w}) & =\frac{1}{2}(\mathbf{y}-\mathbf{X} \mathbf{w})^{\top}(\mathbf{y}-\mathbf{X} \mathbf{w})+\frac{1}{2} \lambda \mathbf{w}^{\top} \mathbf{w} . \\
& =\frac{1}{2}\left(\mathbf{y}-\mathbf{X} \mathbf{X}^{\top} \mathbf{a}\right)^{\top}\left(\mathbf{y}-\mathbf{X} \mathbf{X}^{\top} \mathbf{a}\right)+\frac{1}{2} \lambda\left(\mathbf{X}^{\top} \mathbf{a}\right)^{\top}\left(\mathbf{X}^{\top} \mathbf{a}\right) \\
& =\frac{1}{2}\left\{\mathbf{y}^{\top} \mathbf{y}-\mathbf{y}^{\top} \mathbf{X} \mathbf{X}^{\top} \mathbf{a} - (\mathbf{X} \mathbf{X}^{\top} \mathbf{a})^{\top} \mathbf{y} + \left(\mathbf{X} \mathbf{X}^{\top} \mathbf{a}\right)^{\top} \mathbf{X} \mathbf{X}^{\top} \mathbf{a}\right\}+\frac{1}{2} \lambda \mathbf{a}^{\top} \mathbf{X} \mathbf{X}^{\top} \mathbf{a} \\
& =\frac{1}{2}\left\{\mathbf{y}^{\top} \mathbf{y} + \mathbf{a}^{\top} \mathbf{X} \mathbf{X}^{\top} \mathbf{X} \mathbf{X}^{\top} \mathbf{a}-\left(\mathbf{y}^{\top} \mathbf{X} \mathbf{X}^{\top} \mathbf{a}\right)^{\top}-\mathbf{a}^{\top} \mathbf{X} \mathbf{X}^{\top} \mathbf{y}+\mathbf{a}^{\top} \mathbf{X} \mathbf{X}^{\top} \mathbf{X} \mathbf{X}^{\top} \mathbf{a}\right\}+\frac{1}{2} \lambda \mathbf{a}^{\top} \mathbf{X} \mathbf{X}^{\top} \mathbf{a}  \\
= & \frac{1}{2} \mathbf{a}^{\top} \mathbf{X} \mathbf{X}^{\top} \mathbf{X} \mathbf{X}^{\top} \mathbf{a}-\mathbf{a}^{\top} \mathbf{X} \mathbf{X}^{\top} \mathbf{y}+\frac{1}{2} \mathbf{y}^{\top} \mathbf{y}+\frac{\lambda}{2} \mathbf{a}^{\top} \mathbf{X} \mathbf{X}^{\top}\mathbf{a} \\
& (\mathbf{X}\mathbf{X}^{\top} = \mathbf{K}) \\
= & \frac{1}{2} \mathbf{a}^{\top} \mathbf{K} \mathbf{K} \mathbf{a}-\mathbf{a}^{\top} \mathbf{K} \mathbf{y}+\frac{1}{2} \mathbf{y}^{\top} \mathbf{y}+\frac{\lambda}{2} \mathbf{a}^{\top} \mathbf{K}\mathbf{a} \\
\end {align*}
```  

```math
\begin {align*}
& \mathbf{a}=\frac{1}{\lambda}(\mathbf{y}-\mathbf{X}\mathbf{w}) \\
& =\frac{1}{\lambda}\left(\mathbf{y}-\mathbf{X}\mathbf{X}^{\top}\mathbf{a}\right) \\
& \lambda \mathbf{a}=\mathbf{y}- \mathbf{K}\mathbf{a} \\
& \mathbf{a} = (\mathbf{K} + \lambda \mathbf{I})^{-1}\mathbf{y}
\end {align*}
```
DOMとはなにか

## はじめに

バックエンドを触っているのでフロント側の知識に乏しく、DOMについてもよくわかりませんでした。そしたら現場でjsをたくさん触る機会が増えましたのでこれを機にDOMについてまとめていこうと思います。

## 一言でまとめると

webの画面を動かすための仕組みのことです。

## くわしくまとめると

DOMとは、ウェブページの内容と構造を表すプログラミングインターフェースです。
具体的には以下の通りです。

1. **ツリー構造**
    HTMLやXML文書をツリー構造として表現し、各要素やノードはツリーの一部として位置付けられます。例えば、<html>はルート要素で、その子要素として<head>や<body>があり、さらにその中に他の要素が含まれます

2. **アクセスと操作**
    JavaScriptなどのプログラミング言語を使用して、ページの内容（テキスト、属性、スタイルなど）や構造（要素の追加、削除、移動など）を動的に操作できます。これにより、インタラクティブなウェブページを作成できます

3. **イベントモデル**
    DOMはイベントリスニングとイベントハンドリングの仕組みを提供します。例えば、ユーザーがボタンをクリックしたときの処理を定義したり、フォームの入力内容が変更されたときの処理を記述したりできます

4. **ブラウザ互換性**
    DOMはウェブブラウザに標準的に実装されており、どのブラウザでも基本的に同じ方法で操作が可能です。これにより、クロスブラウザ対応のスクリプトを作成することができます

## おわりに

DOMを理解した後に「仮想DOM」などがあるのでそちらの勉強もしたいので今後勉強していこうと思います。

## 参考資料

https://developer.mozilla.org/ja/docs/Web/API/Document_Object_Model

https://udemy.benesse.co.jp/development/dom.html

https://developer.mozilla.org/ja/docs/Web/API/Document_Object_Model/Introduction

https://zenn.dev/nameless_sn/articles/javascript_dom_tutorial
Windows10サポート終了後の対策２

# Windows10ベースのWindwos Server 2019をインストールする
ご存知のようにWindowsServer 2019はWindows10と同じシステムのはずなのでWindowsServer2019 Essentials 64bitというエディションを使うと約６〜７万円で2029年まで１月９日までの延長サーポー卜を受けられる。

# 使い勝手
WidnosSever2019にOffice365を入れたりOneDriveを入れることもできるので使い勝手はあまり変わらないと思う。

# Windows Subsystem For Linux
WSLも使えたりします。

# サーバーとして使える
当然のことながらサーバーとして動作させることが可能です。
Win10では使えないものも多くあるはず。
（試してないのですがサポートされているプロトコルやサービスはWin10より多いような気がします。）

# 裏技
裏技としてDeveloper使用バージョンがある。
これはあくまでも開発目的で使用することを前提で配布されている。
180日間の期限があり、数回延長可能なので数年は使えるということ・・・
Azure マスターへの道 ~Azure Virtual Desktop~

# はじめに

こんにちは、エンジニアのkeitaMaxです。

Azure初心者がAzureマスターを目指してAzureのLearnなどを進めていくための備忘録として書いています。

今回は前回に引き続き、Learnの「**Azure コンピューティングおよびネットワーク サービスについて説明する**」をやっていきます。

https://learn.microsoft.com/ja-jp/training/modules/describe-azure-compute-networking-services/

# Azure Virtual Desktop について

クラウドで実行されるデスクトップの仮想化サービスと書かれていました。

すきなバージョンのWindowsを使用することができるそうです。

セキュリティ的にもは、ローカルのハードウェアからデータなどが切り離されるので、個人のローカルPCに機密データを残してしまうリスクが軽減できます。

# VMとの違い

VMはWindowsだけでなくLinuxも使用することができます。

また、AVDは複数のユーザ同時にアクセスできる仮想デスクトップ環境を提供しているのに対し、VMは単一ユーザーが使用するデスクトップ環境や、特定のアプリケーションやサービスをホストするためのサーバー環境を提供しているらしいです。
（ChatGPTに聞きました。。。）

# おわりに

この記事での質問や、間違っている、もっといい方法があるといったご意見などありましたらご指摘していただけると幸いです。

最後まで読んでいただきありがとうございました！

# 参考

https://www.linkedin.com/pulse/azure-virtual-machine-vs-desktop-virajoautosoft

# まとめ

https://qiita.com/keitaMax/items/1eda90987f21cabd3659
暗黙的送信（Implicit submission）について


# はじめに

最近触っていたコードの中で以下のような処理を見つけました。

```javascript
$("input[type='text']").on("keypress", (e) => {
  if (e.keyCode === 13) {
    $("form").valid();
    return false;
  }
});
```

パッと実装意図が分からず、調べる中で学びがあったので、メモとして残そうと思います。

# 該当コードの実装意図

結論からいくと、Enter キーによる form 送信を防ぐためでした。
input 要素にフォーカスしている時に、Enter キーを押すと送信されてしまう場合があります。
この挙動はユーザーの意図しない送信を誘発する可能性があるため、
送信ボタンをクリックしたときだけ submit する形にしていると思われます。

# Enter キーによる送信

Enter キーによる送信は`暗黙的送信（Implicit submission）`と呼ばれる仕様であり、
WHATWG の仕様書には以下のような記載があります。

https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#implicit-submission

> 4.10.21.2 Implicit submission
>
> A form element's default button is the first submit button in tree order whose form owner is that form element.
>
> If the user agent supports letting the user submit a form implicitly (for example, on some platforms hitting the "enter" key while a text control is focused implicitly submits the form), then doing so for a form, whose default button has activation behavior and is not disabled, must cause the user agent to fire a click event at that default button.
>
> > Note：There are pages on the web that are only usable if there is a way to implicitly submit forms, so user agents are strongly encouraged to support this.
>
> If the form has no submit button, then the implicit submission mechanism must perform the following steps:
>
> - If the form has more than one field that blocks implicit submission, then return
> - Submit the form element from the form element itself with userInvolvement set to "activation"
>
> For the purpose of the previous paragraph, an element is a field that blocks implicit submission of a form element if it is an input element whose form owner is that form element and whose type attribute is in one of the following states: Text, Search, Telephone, URL, Email, Password, Date, Month, Week, Time, Local Date and Time, Number

上記の内容を整理すると、

- form には default ボタンという概念があり、form 内の最初に登場する submit ボタンが default ボタンとして扱われる
- 暗黙的送信が起こると、（disable でない限り）default ボタンの click イベントが発火
- form 内に submit ボタンが存在しない場合も、input 要素が 1 つなら、暗黙的送信が起こる

つまり、form 内に input 要素が複数あり、submit タイプのボタンが存在しない場合以外のフォームでは暗黙的送信が起こるということになります。

# 改めて該当処理の必要性を検討

上記を踏まえて、改めて該当処理の必要性を検討します。
submit タイプの代わりに button タイプのボタンを置き、js でバリデーションチェック後に submit させる作りであれば、暗黙的送信は起こらない可能性が高そうです。
ただ、画面の input 要素が 1 つになる場合もあるし、submit タイプのボタンが置かれる可能性もあります。
よって、該当処理は必要なのだと判断しました。
インストールしたけどパスが通っていなかった

# 起こったこと

```bash
go install github.com/deepmap/oapi-codegen/v2/cmd/oapi-codegen@latest

oapi-codegen -version
> command not found: oapi-codegen
```

oapi-codegenを使用してGoのコード自動生成を行おうとしていました。
インストールを実行したはずなのに、コマンドが見つからないようです。

# やったこと

oapi-codegenはgoのバイナリファイルにインストールされるので、Goのパスを確認します。

```bash
go env GOPATH
> /home/username/go
```

すでに通っているパスを確認します。

```bash
echo $PATH
> /usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
```

この中にさきほど確認したGoのパスがないので、パスを通してやる必要があるとわかりました。

```bash
export PATH=/home/username/go/bin:$PATH
```

```bash
echo $PATH
> /home/username/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
```

しかし、上記だけでは永続的にPATHが通らないです。
毎回同じ操作をするのが面倒であれば`.bashrc`にPATHを追加する必要があります。

まずは好きなエディタで`.bashrc`を開きましょう。

```bash
// vim
sudo vim ~/.bashrc

// nano
sudo nano ~/.bashrc
```

`.bashrc`を開けたら、ファイル末尾に以下を追加します。

```.bashrc
export PATH=$PATH:/home/username/go/bin
```

ファイルを保存したら、以下のコマンドで変更を有効にします。

```bash
source ~/.bashrc
```
【Progate】Command Lineコースを終えての所感

## 自己紹介
29歳。文系卒。新卒入社でWebディレクターを２年半経験。
その後は番組の字幕制作の仕事に従事。
現在はエンジニア転職を目指して勉強中。

## Command Lineの印象
数日レベルですが、実務で扱ったことがあります。独学でプログラムを作るときにも触ってますが、印象としては、コンピューターに直接命令するんだな～くらいの感じです。


## 覚えておきたいこと

というか、このレッスンで学んだプロンプト一覧です。
```
// 空のファイルを作成
$ touch ファイル名 

// ファイルを開く
$ cat ファイル名

// ディレクトリを作成
$ mkdir ディレクトリ名

//ディレクトリ変更(パスなしでホームディレクトリへ)
$ cd 相対パス

// カレントディレクトリの表示(print working directory)
$ pwd

//ディレクトリ内を表示(list)
$ ls

//ファイル or ディレクトリ移動(move)
$ mv ファイル(ディレクトリ)名  移動先ディレクトリ名

//ファイル or ディレクトリ名前変更(move)
$ mv ファイル(ディレクトリ)名  新しいファイル(ディレクトリ)名

//コピー(copy)
$ cp ファイル名 新しいファイル名

// ディレクトリごとコピー
$ cp -r ディレクトリ名 新しいディレクトリ名

//削除(remove)
$ rm ファイル名

//ディレクトリごと削除
$ rm -r ファイル名

```

なお、Tabキーを押すとファイル名を補完してもらえる。
↑↓キーで直近使ったプロンプトを再利用できたりもする。

## まとめ
特に印象が様変わりしたりはしませんでしたが、ここにこうして一覧を作れたことは後に役立つでしょう。

今後も継続して学習を続けていきたいと思います。

[Progate](https://prog-8.com/)
目標達成　Easy-ISLisp 並列機能、強化

# 目標達成
2024年4月13日、私はEasy-ISLisp ver4.0をリリースしました。念願の並列機能を充実させました。マルチプロセス方式、マルチスレッド方式、まともに動作するようになりました。並列に取り組んで1年ほどかかりました。感無量です。

![bandicam 2024-06-14 07-58-13-095.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/f83fb54e-5e09-e645-911b-7105b43b3d31.jpeg)


# 初めての出会い
あれは1980年頃のことでした。秋葉原でパソコンに出会いました。知的なショックでした。個人でもコンピューターが買えるということに驚きました。その後しばらくしてLispとPrologに出会いました。これは私の長年の教師、友人たちです。ずいぶんと多くのことを私は学びました。

![bandicam 2024-06-14 08-01-20-335.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/30b52dc1-df15-6a31-8dc4-0a2fc5e75708.jpeg)



# 休養
目標を達成したので私はしばらく休養、のんびりしようと思っています。ジャズバンドからお誘いがありました。ギター、音楽で楽しみたいと思っています。


でも、また心の底からコンピューターに取り組みたくなる日がくるかもしれません。それではしばらくお休みです。みなさんありがとう。

https://github.com/sasagawa888/eisl
「コミュニケーション能力が高い」エンジニアとは

# はじめに
「コミュニケーション能力」
大事ですよね。

まず、「コミュニケーション」と聞いて、みなさんは何を想像しますか？

雑談、会議、プレゼン、面接、1on1、接客、電話対応、SNS、スピーチ、挨拶など、様々なものがあると思います。

では、「コミュニケーション能力が高い」エンジニアとは、どのようなエンジニアなのでしょうか。

# 辞書ではどう定義しているか
コミュニケーション能力：
社会生活において、他者と円滑に意思の疎通が行える能力。（デジタル大辞泉）

# 開発業務における意思の疎通とは
エンジニアの開発業務における意思の疎通について考えてみます。

- 要望の洗い出し
- 要件や仕様の理解
- レビューにおける分かりやすい説明
- 不明点や疑問点の質問
- 分かりやすい進捗報告
- 的確かつ簡潔な障害報告
- メンバーに対するヒアリング

他にもあると思いますが、すぐに思い付くだけでも、これだけあります。

それでは、これらをうまくやるには、何が必要なのでしょうか。
これまでの経験から、リストアップしてみます。

### ヒアリング系
- 背景や経緯、意図の説明
- ヒアリングした内容の認識合わせ
- 他にないか、別視点からの確認

### 報告系
- 概要（何に関する報告か）
- どのような状況か
- 背景や経緯、根拠の説明

### 質問系
- 知りたいことは何か
- 何をどこまでやったのか
- その結果、何に困っているのか

# 結局どういうことか
辞書の内容と上記から考えると、

**他者と円滑に意思の疎通を行うための準備**

が必要で、これを状況に応じてきちんとやれるエンジニアが、コミュニケーション能力が高いエンジニア、ということになります。

楽しい会話ができるだけではだめで、業務を円滑に進めるための、丁寧な準備が必要です。

開発現場あるあるですが、コードレビューとかもそうですよね。
すぐに終えるつもりが、あまり準備せずに臨むと、普通に1〜2時間かかってしまいます。

しかし、簡潔に伝えるための準備をすると、15〜20分くらいで終えることができるんです。

これだけ短縮化できれば、コードレビュー疲れも起こらず、プロジェクト全体が活性化しますね。

まさに、業務を円滑に行えている、ということになります。

参考までに、以前、[コードレビューの効率化](https://qiita.com/yam_dev/items/52957b950d35ac7e7ec0)について記事を書いたので、よろしければ、こちらもご覧ください。

# まとめ
今回は、コミュニケーション能力が高いエンジニアについて考察してみました。

結局のところ、一人の社会人として、相手に伝えたり、相手を理解するための行動を、どこまで入念にやれるか、というのが大事です。

このような作業の積み重ねが、エンジニアとしてだけでなく、社会人としての成長や、大きなチャンスにつながります。

みなさんも、一緒に丁寧に取り組んでいきましょう！
【Python】multiprocessing使ってみた

Pythonでは```multiprocessing```モジュールを使うと、プロセスを複数立ち上げて並列処理を行うことができます。
これにより、特にマルチコアプロセッサを搭載したコンピュータで処理速度の向上が見込めます。基本的な使い方をいくつか紹介します。

ということなので今更ながら試してみます。

## プロセスの作成と実行
シンプルなパターン
Processに実行する関数を渡す。
argsで引数を渡す。

```python
import multiprocessing

def worker(number):
    """仕事をするワーカー関数"""
    print(f'Worker: {number}')

if __name__ == '__main__':
    # プロセスのリスト
    processes = []
    
    # 5つのプロセスを作成
    for i in range(5):
        p = multiprocessing.Process(target=worker, args=(i,))
        processes.append(p)
        p.start()
    
    # 全プロセスの終了を待つ
    for p in processes:
        p.join()

```

ちゃんと動いていることがわかる。
引数も使えている。
```text
Worker: 0
Worker: 1
Worker: 2
Worker: 3
Worker: 4
```

## データの共有
プロセス間でデータを共有するパターン
Value や Array などの共有メモリオブジェクトを使用する。
```python
import multiprocessing

def increment(shared_number):
    """共有メモリ内の数値をインクリメントする"""
    with shared_number.get_lock():
        shared_number.value += 1

if __name__ == '__main__':
    # 共有メモリオブジェクトの作成
    shared_number = multiprocessing.Value('i', 0)  # 'i' は int 型を意味する
    
    # プロセスのリスト
    processes = []
    
    # 100個のプロセスを作成し、共有メモリの数値をインクリメント
    for _ in range(100):
        p = multiprocessing.Process(target=increment, args=(shared_number,))
        processes.append(p)
        p.start()
    
    # 全プロセスの終了を待つ
    for p in processes:
        p.join()
    
    print(f'Final value: {shared_number.value}')

```

ちゃんとプロセス数分インクリメントされている。
```text
Final value: 100
```

## プールを使う
複数のプロセスにタスクを分配するためにプールを使用するパターン
特定数のプロセスでタスクを効率的に実行できる。

```python
from multiprocessing import Pool

def square(number):
    return number * number

if __name__ == '__main__':
    with Pool(5) as p:
        results = p.map(square, range(10))
    print(results)

```

タスクが分配されている様子は正直わからないが、分配されていることであろう。。。
```text
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
```

## まとめ
これまでmultiprocessingを使わずにシングルプロセスで動作させてばかりだったが、状況によっては非同期で実行させたい場合もあるし試してみてためになった。
もっとちゃんと使っていきたい。
【Progate】JavaScriptコースを終えての所感

## 自己紹介
29歳。文系卒。新卒入社でWebディレクターを２年半経験。
その後は番組の字幕制作の仕事に従事。
現在はエンジニア転職を目指して勉強中。

## JavaScriptの印象
「JavaとJavaScriptは名前が似てるだけでまったく別物」という話をよく耳にしていました。

なので少し身構えていたのですが、蓋を開けてみればほとんどJavaで、特にクラスや継承のあたりでJavaの系譜を感じました。「まったく別物」というのは、書き方以外のところを指していたのかもしれません。もっとも、これまでに私がしっかりと学んだ言語がJavaだけだからそう感じるのかもしれませんが…。

とにかく、親しみを感じながら[Progate](https://prog-8.com/)を終えることができました。

## 覚えておきたいこと
#### アロー関数

キュッと縮めたコードで関数を定義する。この書き方がノーマルらしい。
Javaでいうラムダ式のようなものでしょうか。


#### コールバック関数

```javascript
const doSomething = () => {
  // 処理
};

const call = (callback) => {
  // 以下で doSomething()が呼び出される
  callback();
};

// 関数の定義そのものを引数にしている
call(doSomething);
```
コールバック関数とは、他の関数に **引数として渡される関数** のこと。
使いどころがまったくわかりませんが、うまく活用すれば柔軟なコードが書けることはわかります。

## まとめ
今回の学習を通じて、JavaScriptの基礎をしっかりと理解することができたと思います。
身に付けるには反復する必要がありそうですが、ひとまずはよしとします。

久しぶりにProgateを使いましたが、やはり初めて触る言語をサクッと学ぶにはかなり優秀だなと感じました。

今後も継続して学習を続けていきたいと思います。
【Java】抽象クラスの継承を覚える

通常のクラスの継承に対して、抽象クラスの継承は何が違うのか、覚えるための自分用メモです。

# 抽象クラスとは？
抽象クラスでは、一部のメソッドを抽象メソッド（```abstract```）として記述することで、継承したサブクラスでのオーバーライド（実装）を強制します。
# サンプルプログラム
例えば、以下のクラスを```SubClass1```クラスに継承するとします。
```java:SuperClass.java
public abstract class SuperClass {
    private String name;
    public SuperClass(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public abstract String talk();
}
```
以下のようにオーバーライドすれば問題ありませんが、オーバーライドしなかった場合はコンパイルエラーになります。
```java:SubClass1.java
public class SubClass1 extends SuperClass {
    public SubClass1(String name) {
        super(name);
    }
    @Override
    public String talk() {
        return "こんにちは。" + name + "です。";
    }
}
```
また、抽象クラスは直接インスタンス化できないので、単体では使えない「継承のためのクラス」と言えますね。
## 継承したサブクラスをインスタンス化する
抽象クラスを継承したサブクラスをインスタンス化する記述は、通常のインスタンス化と変わりません。
```java:Main.java
public class Main {
    public static void main(String[] args) {
        SuperClass superClass = new SubClass1("名前1");
    }
}
```
## オーバーライドしたメソッドを呼び出す
オーバーライドした抽象メソッドは、通常のメソッドと同様に呼び出すことができます。
```java:Main.java
public class Main {
    public static void main(String[] args) {
        SuperClass superClass = new SubClass1("名前1");
        print(superClass);
    }
    static void print(SuperClass superClass) {
        System.out.println(superClass.talk());
    }
}
```
**実行結果**
こんにちは。名前1です。
widthとheightを指定しているのに縦横が揃わない

# 事象
Webページを作成した際に、テキストボックスなど複数の要素を横幅指定して並べていたところ、横幅が揃わずがたがたになってしまった。
以下のサンプルを見てもらうとわかる通り、すべての要素に幅250px、高さ30pxを指定しているがどう見てもそうは思えない。

<p class="codepen" data-height="300" data-theme-id="dark" data-default-tab="html,result" data-slug-hash="Baemxgj" data-pen-title="高さ・幅が揃わない" data-user="Mio-K0408" 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/Mio-K0408/pen/Baemxgj">
  高さ・幅が揃わない</a> by M (<a href="https://codepen.io/Mio-K0408">@Mio-K0408</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# 考えたこと
開発ツールを用いて1つずつ要素を確認していくと高さや幅の指定がちゃんと効いてはいる。要素ごとに縦横の指定の反映の仕方が異なるのかと思い1つずつwidthやheightの指定を細かく設定しないといけないのかと思ったがそんなことはしたくないので方法を調べた。

# 実際の解決方法
CSSで横幅や高さを指定するとデフォルトで「box-sizing:content-box」が設定されているらしく、それにより要素自体の縦横は指定できても、追加でpaddingなどが付与されてしまう。
そうではなく、指定した縦横に余白込みで揃えたいときは以下を設定すると良い。
```
box-sizing: border-box;
```
これにより余白などすべて含めたうえで指定したサイズになってくれる。
<p class="codepen" data-height="300" data-theme-id="dark" data-default-tab="html,result" data-slug-hash="xxNPjva" data-pen-title="高さ・幅をそろえる" data-user="Mio-K0408" 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/Mio-K0408/pen/xxNPjva">
  高さ・幅をそろえる</a> by M (<a href="https://codepen.io/Mio-K0408">@Mio-K0408</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

確かに、最初のと比べるときれいに要素が揃っている。
フロントを触る機会が増えてきたがなかなかがっつりHTMLやCSSを触る機会がないので疑問に思ったことやしっくりこないことを調べて随時キャッチアップしていくことの大切さを実感した。レイアウトをきれいにするって本当に大変。


# 参考記事
https://webst8.com/blog/css-box-sizing/#:~:text=box-sizing%E3%81%AFborder%E3%82%84,%E3%81%8C%E3%81%A7%E3%81%8D%E3%82%8BCSS%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3%E3%81%A7%E3%81%99%E3%80%82
あのとき挫折した技術的な話が今は簡単に分かる理由について考察する

若かりし頃に、技術的に何かでつまづいた経験はありませんか。環境構築、言語習得、トラブルシューティングなど。  
私は大学 1 年のころに PC もあまり触ったことがない状態でいきなり C 言語と $ \LaTeX $ を書かされ、プログラミングなんて二度とやるもんか、と思った経験があります。

でも今は、そのプログラミングを武器に仕事をしているし、C 言語ではないけど様々な言語を習得していて、「なぜかできるように」なっています。  

その理由は何でしょうか。「そりゃあ成長してるからそうだろ」と思っていましたが、よくよく考えると結構不思議なことだったりもするので、ちゃんと考察してみようと思います。

## 理由

### エンジニア界隈の英語がわかるようになった

英会話ができなくても、専門用語の読み書きができるようになるだけで自分に入ってくる情報は大幅に増えます。  
英語での検索力が向上しますし、エラーメッセージの意味も分かるようになります。（読めなくても翻訳すれば OK）

### IDE を使うことで実行前からエラーが分かることが多くなった

大学で情報の授業を受けていた時は、大学の視聴覚室にある Linux (GUI つき) でただただ白いメモ帳で C 言語を書いていました。そのため、教科書通りにやってもエラーになることが多かったし、なによりどこがエラーになっているのかさっぱりわからなかったです。

今では Windows (や Mac) 上でも C 言語を書く環境が作れることを知っているし、ポケットマネーで高級な IDE を使えるようになったため、半角・全角スペースの視認性も上がり、文法エラーも実行前に気付けるようになりました。
大学のころは自分の PC で C 言語が書けるなんて考えたこともなかったですけど。

ちなみに、学生は JetBrains 社のエディタを無料で使えるみたいです。教育目的であれば。

https://blog.jetbrains.com/ja/2019/08/22/2105/

### Docker によって環境の構築・破壊が簡単にできるようになった

若かりし頃は、PC に何か変な奴をいれて PC が壊れたらどうしよう、とか考えていたので、何かいろいろ試すなんて怖くてできなかったんですが、今では Docker を利用して簡単に何かを試すことができますし、Windows PC の中に Linux 環境を構築することもできます（WSL2）。  
これによって、Windows に直接インストールする方法がダメなら WSL2 に入れてみようだとか、WSL2 がダメなら Docker、Docker がダメなら AWS に EC2 インスタンスを作って試そうとか、いろいろな選択肢を取れるようになりました。選択肢が増えるわけですから、当然成功確率は爆上がりするわけです。

### 教育コンテンツが充実した

英語が分かることによって、海外の学習コンテンツも読めるようになり、結果として学習スピードが向上することが多いです。  
また、お金があれば、Udemy などの有料コンテンツに対してお金を使うことができます。  
実際、私が嫌になったはずのプログラミングに返り咲いたのは、[Progate](https://prog-8.com/) というプログラミング学習サイトに月額 980 円（当時）を課金して全コンテンツを 2 周し、プログラミングを仕事にすることの敷居が 500 段くらい下がったことにあります。

また、近年では教育系 YouTube コンテンツの増殖により、動画で説明を受けられる機会が大幅に増えました。動画では活字に加え、音声による説明も加わるため、結果的に理解度の向上につながりました。

## まとめ

長々と書きましたが、結局、自分の技術力のきっかけになっているのは

- 英語
- 金
- YouTube

の 3 つです。  
3 つのうち 1 つでも備わっていれば、エンジニアとして十分に成長することが可能です。3 つともそろっていたらなお良しです。1 つも無くても、意欲さえあれば何とかすることが可能です。
PowerShellでCopilotを使ってみた

[PowerShellでCopilotを使える](https://qiita.com/ms-windows3_1/items/cea5134537b074a9a51e)ようにした。

なかなか便利である。私の環境では、日本語で入力するとPowerShellだけでなくターミナルもコマンドも、なぜかすべて落ちてしまうので、簡単な英語で質問するだけだが、PowerShellのコマンドを知らない身には、大変にありがたい。

よく使うのが、ファイル検索。PowerShellのコマンド名はやたら長い。
```
DIR /S *filename*
```
こんなシンプルにはならない。

```
PS C:\Users\Windows3_1> copilot suggest 'command same as DIR /S *SSS* on powershell'

Welcome to GitHub Copilot in the CLI!
version 1.0.3 (2024-05-08)

I'm powered by AI, so surprises and mistakes are possible. Make sure to verify any generated code or suggestions, and share feedback so that we can learn and improve. For more information, see https://gh.io/gh-copilot-transparency

? What kind of command can I help you with?
> generic shell command

Suggestion:

  Get-ChildItem -Recurse | Where-Object { $_.Name -like '*SSS*' }

? Select an option
> Copy command to clipboard

Command copied to clipboard!
```
しかし、copilotでコマンドを教えてくれて、それをクリップボードにまでコピーしてくれるから、非常に楽ちんである。

質問するときに"on powershell"としないと、普通にbashの解説をされてしまう。

もちろん日本語で質問しても、問題なし。

```
PS C:\Users\Windows3_1> copilot suggest 'powershellで隠しファイルを表示したい'

Welcome to GitHub Copilot in the CLI!
version 1.0.3 (2024-05-08)

I'm powered by AI, so surprises and mistakes are possible. Make sure to verify any generated code or suggestions, and share feedback so that we can learn and improve. For more information, see https://gh.io/gh-copilot-transparency

? What kind of command can I help you with?
> generic shell command

Suggestion:

  Get-ChildItem -Hidden | Select-Object FullName
```
MS-DOSやunix（Lunixではない！！！）のコマンドは体が覚えている。viは指が自然に動くが、nanoなんて名前も聞いたことが無いから、使ったことが無い。ちなみに、当時でもemacsは使わなかった。

だからPowerShellだのwslとやらのコマンドは、まったくわからぬ！！！！教えたまえ、copilot!!
```
PS C:\Users\Windows3_1> copilot suggest '現在アクティブなwslインスタンスを表示する'

Welcome to GitHub Copilot in the CLI!
version 1.0.3 (2024-05-08)

I'm powered by AI, so surprises and mistakes are possible. Make sure to verify any generated code or suggestions, and share feedback so that we can learn and improve. For more information, see https://gh.io/gh-copilot-transparency

? What kind of command can I help you with?
> generic shell command

Suggestion:

  wsl --list --running

? Select an option
> Copy command to clipboard

Command copied to clipboard!
PS C:\Users\Windows3_1> wsl --list --running
Linux 用 Windows サブシステム ディストリビューション:
Ubuntu-22.04 (既定)
```

お前は賢いのぉ。高いくせに何の役にも立たぬMicrosoft Copilotとは、大違いじゃ！！！
Javaで「配列の長さを取得する(length)」の動作を確認してみた

# 概要

Javaで「配列の長さを取得する(length)」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/start/array/index6.html

# 実装

以下のファイルを作成しました。
```JSample6_1.java
class JSample6_1{
  public static void main(String[] args){
    double[] num = new double[3];

    num[0] = 5.24;
    num[1] = 8.0;
    num[2] = 12.375;

    for (int i = 0; i < num.length; i++){
      System.out.println("num[" + i + "] = " + num[i]);
    }
  }
}
```

以下のコマンドを実行しました。
```
$ javac JSample6_1.java 
$ java JSample6_1 
num[0] = 5.24
num[1] = 8.0
num[2] = 12.375
```

# まとめ

何かの役に立てばと。
一時期twitterで話題になったエレコムのAPを買ってした設定

一時期Twitterで爆発的に話題になったエレコムの例のAPこと、WAB-I1750-PS。
10年ものの型落ちと言え、定価3万6000円の業務用の製品の新品が1800円しないくらいで買えたのはアツかった。
[^1]<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おお！エレコム法人向けAP祭り、在庫復活してた。一台Get!<a href="https://t.co/65xRqPli3h">https://t.co/65xRqPli3h</a> <a href="https://t.co/atuK11WSdu">pic.twitter.com/atuK11WSdu</a></p>&mdash; イチロヲ📛 (@ichirowo) <a href="https://twitter.com/ichirowo/status/1762461749528412328?ref_src=twsrc%5Etfw">February 27, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 　


現在は公式の方でも定価の3万6000円で売っており、また、中古もパット見た感じ5000円台と割高感が否めないため、今から買うのはオススメできない。今回は私がセットアップして効果的だった設定等を紹介する。

# 目次
[1.買ったらインターネットに繋げずセットアップしよう。](#1-買ったらインターネットに繋げずセットアップしよう)
[2.ipアドレスを固定しよう。](#2-ipアドレスを固定しよう)
[3.速さを求めるならオートチャンネルをオフにしよう。](#3-速さを求めるならオートチャンネルをオフにしよう)
[4.再起動スケジュールを設定しよう](#4-再起動スケジュールを設定しよう)
[5.まとめ](#5-まとめ)

 

# 1. 買ったらインターネットに繋げずセットアップしよう。


まず、買ってビビったのが最初から無線がオンじゃないという点に驚いた。やはらそこは業務用だなと思った。LanポートがあるPCがないとWi-Fiがオンにできないから気をつけたほうがいい。
そして最初にインターネットに繋いではならない。インターネットに繋いだら振られるipアドレスが変わっちゃうから設定画面に入らなくなる。私はここで詰まった。そのため、最初はLanケーブルとパソコンだけを繋いでセットアップしよう。
設定画面には
- パソコンのIPアドレスを192.168.3.2
- サブネットマスクを255.255.255.0

にしてから
- ブラウザのアドレスバーに192.168.3.1と打つと入れる。

# 2. ipアドレスを固定しよう。
インターネットに繋いだらルータが勝手にipアドレスを振っちゃうので毎回ログインするためのipアドレスが変わってしまう。そのため、最初から固定しよう。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757476/b339ff66-9900-d8c4-cf4c-8718d506a286.png)
システム構成のLan側IPアドレスのところで変えよう。

私は以下のように変更した。

- IPアドレス割り当て　→　静的アドレス
- IPアドレス →　好きなアドレスに。ルーターのアドレスと最後の数字以外一緒のほうが後々助かる。 例　ルーターのアドレスが192.184.1.1なら192.184.1.2のように最後のコンマの後だけ変える。
- サブネットマスク　→　ルーターと同じでいいと思う。
- デフォルトゲートウェイ　→　ルーターを指定しよう。ここは設定しなくても問題なく動作するが、設定したほうが後々助かる。windowsならコマンドプロンプトでipconfigと打つとわかる。



### DNSサーバー

私はcloudflareのやつを使っている。他にもgoogleとかあるから好きなのを設定しよう。

- プライマリアドレス　→　cloudflareは1.1.1.1 　　googleは8.8.8.8
- セカンダリアドレス　→　cloudflareは1.0.0.1　　 googleは8.8.4.4



# 3. 速さを求めるならオートチャンネルをオフにしよう。

Wifiはチャネルが高いほど速度が出る。オートチャンネルだとふとした拍子に低いチャネルが選択され遅くなる。安定性を求めるならそれで問題ないが、常に速さを求めるならチャネルを固定しよう。[Wifi analyzer](https://apps.microsoft.com/detail/9nblggh33n0n?hl=ja-jp&gl=JP)とかで周りに干渉する周波数がないことを確認して固定しよう。
### 選び方
チャンネル帯域幅が最大のやつが選べ、その中で選べる最大のチャネル。今回の場合、最大のチャネル帯域幅の80MHzが選べるのが、128までなので特に問題ない場合128を選んだほうがいいだろう。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757476/aa26d3e0-ff99-cb5e-2e09-4e2816c9f247.png)

# 4. 再起動スケジュールを設定しよう

今回のAPは定期的に再起動しないと不安定になる。そのため、再起動スケジュールを設定しよう。そのためには日時をNTPで同期しないといけない。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757476/1a93096e-9ac7-1117-d247-73048f494f37.png)
NTPタイムサーバーを有効にしよう。この際、2で紹介した通りにIPアドレスとデフォルトゲートウェイが設定できないと同期できない。
次に再起動スケジュールを設定しよう。これは普通に設定で有効にして、スケジュールを設定するだけでできる。


# おまけ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757476/c5184b2e-4a05-fe30-3efa-a98ef8b91bed.png)
私は「速度と通信方式」の設定のところを自動ではなく、1000Mbps全二重通信方式にしてる。効果は実感できないが、自動より良いだろうとなんとなくしている。



# 5. まとめ
速度は300Mbpsくらいと現代だと遅く感じるが、実用上は問題ない。POEが使えたり、細かく設定できるのは嬉しいが、高く見積もっても現代では3000円くらいの価値しかないと思う。それ以上出すなら新品で市販のAP買ったほうが楽だし、速度が早く幸せになれると思う。コンセント周りがごちゃごちゃしなくなったのはPOEにしてよかったなと思っている。



[^1]:  他の方のツイート
Ubuntu(Virtual Box)のシステムフォルダを英語名に変更してみた

参考サイト
https://armadillo.atmark-techno.com/blog/8700/3599

# 日本語から英語へ変更する
```terminal:terminal
LANG=C xdg-user-dirs-gtk-update
```

# メッセージが表示されるので設定する
- uptate namesをクリックする
![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/f715ebe6-09b7-0164-1216-9969cb9fcd12.png)

- Don't ask me this againにチェックを入れても再起動後にメッセージが表示された


# 再起動する
```terminal:terminal
reboot
```

# メッセージが表示されるので設定する
- 次回から表示しないにチェックを入れる
- 古い名前のままにするをクリックする

![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/3a772035-3e37-584c-91dd-1931db5bbe53.png)
CyberAgentLM2について

# CyberAgentLM2とは

 **2024年6月13日** に株式会社サイバーエージェントから公開された75億パラメータの日本語のVLMである．商用利用可能な画像チャットモデルである．

# VLM(大規模視覚言語モデル)とは

画像やテキストから学習できるマルチモーダルモデルとして広く定義されている．画像とテキストの入力を受け取り，テキスト出力を生成する生成モデルの一種である．現在，既存で公開されているVLMは，英語が中心とした学習のため，日本文化の理解や日本語での会話に強いVLMは少ない状況である．

# CyberAgentLM2で遊んでみる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3815462/9dfc4183-e13d-e24f-ee4e-a91c936c3cdb.png)

スペイン料理のパエリアの味を詳しく教えてもらう．
中身の食材を判別出来ているが，料理名は，判断できてなさそう．

<br>

次に，日本特有である **着物** について説明してもらう．
着物や帯の柄を説明できている．加えて，背景の説明もされている．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3815462/3ef17813-36f4-6aed-8e88-eef16c4e8e54.png)

<br>
最後に，だんじりについて行ってみる．下の画像を見てわかる通り，だんじりという特定の言葉は説明文に記載されていなかったが，「山車」や「法被」など，日本の文化特有の言葉は，画像から認識することが出来ている．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3815462/79df8b92-c7d2-1a8f-6c54-d2a0753b2f7d.png)

# 最後に
今回は，CyberAgentLM2を簡単に取り上げた．今後，もう少し詳しく触って，わかったことがあれば，追記をしたいと思う．今回が，初執筆なので，慣れない部分が多く，読みにくいと感じた方がいるかもしれない．これから，そのようなことがないように工夫を施していきたいと考える．
# 参考文献
-[Vision Language Modelの技術詳細と推論と学習](https://note.com/npaka/n/n76fb29eadbe6)

-[Vision Language Models Explained](https://huggingface.co/blog/vlms)

-[独自の日本語LLM「CyberAgentLM2」に視覚を付与したVLM(大規模視覚言語モデル)を一般公開―商用利用可能な画像チャットモデルを提供-](https://www.cyberagent.co.jp/news/detail/id=30344)
【TryHackMe】Intro to Defensive Security：Walkthrough

# 概要

TryHackMe「Intro to Defensive Security」のWalkthroughです。

https://tryhackme.com/r/room/defensivesecurity

# Task1

## **Q1**.*Which team focuses on defensive security?*

**A**.**Blue team**

# Task2

## **Q1**.*What would you call a team of cyber security professionals that monitors a network and its systems for malicious events?*

**Hint**.*SOC*

**A**.**Security Operations Center**

## **Q2**.*What does DFIR stand for?*

**A**.**Digital Forensics and Incident Response**

## **Q3**.*Which kind of malware requires the user to pay money to regain access to their files?*

**A**.**Ransomware**

# Task3

## **Q1**.*What is the flag that you obtained by following along?*

**A**.**THM{THREAT-BLOCKED}**
CloudFlareにデプロイするためのRemixプロジェクトでフレッシュマイグレーション + seed実行の仕組みを作ってみる

## 概要

Remix + Prisma + CloudFlareのD1という構成だとフレッシュマイグレーション + seed実行のようなコマンドは用意されていないため自前で用意してみる。

## 前提

- - CloudFlare上のD1データベース名は「todo-cloudflare-d1」とする。よってwrangler.tomlでdatabase_nameが`todo-cloudflare-d1`と指定されている
- 下記の内容が完了している

https://qiita.com/miriwo/items/04c983597082a23c3524

https://qiita.com/miriwo/items/1cfb05c9501f9cb18b07

## 方法

1. フレッシュマイグレーションの流れは「テーブル削除」 → 「マイグレーション実行」のためその流れを作成
1. 下記を実行してseedsディレクトリ直下に`drop_tables.sql`を作成

    ```sh
    touch seeds/drop_tables.sql
    ```

1. `seeds/drop_tables.sql`を下記のように記載

    ```seeds/drop_tables.sql
    -- DropTable
    -- マイグレーション管理テーブルリセット
    DELETE FROM d1_migrations;
    -- NOTE: テーブルを追加したらこちらにも忘れず追記
    DROP TABLE IF EXISTS tasks;
    DROP TABLE IF EXISTS task_category_masters;
    DROP TABLE IF EXISTS users;
    ```

1. 下記を実行してテーブルが削除されることを確認

    ```sh
    npx wrangler d1 execute todo-cloudflare-d1 --local --file ./seeds/drop_tables.sql
    ```

1. テーブルが一部削除されていることを確認
1. 下記を実行してマイグレーションが通ることを確認

    ```sh
    npm run migrate
    ```

1. 下記を実行してseedを流しデータが入ることを確認

    ```sh
    npm run seed
    ```

1. ここまでが無事通ったら実装は問題ない

## 一発でマイグレーションリセット（テーブル削除していちからマイグレーション実行）できるコマンドを用意

1. 下記をpackage.jsonのscriptsに記載

    ```package.json
    {
      "scripts": {
        "local-migrate-fresh": "npx wrangler d1 execute todo-cloudflare-d1 --local --file ./seeds/drop_tables.sql"
      }
    }
    ```

1. これで下記を実行することでマイグレーションフレッシュする事が可能

    ```sh
    npm run local-migrate-fresh
    ```

1. 下記をpackage.jsonのscriptsに記載

    ```package.json
    {
      "scripts": {
        "local-migrate-reset": "npm run local-migrate-fresh && npm run local-migrate"
      }
    }
    ```

1. これで下記を実行することでマイグレーションリセットをする事が可能

    ```sh
    npm run local-migrate-reset
    ```

## 更に便利になりそうなコマンドを追加

コマンドを入れ子実行するようにして便利なコマンドを作っておいた。

```package.json
"scripts": {
  "build": "remix vite:build",
  "deploy": "npm run build && wrangler pages deploy",
  "dev": "remix vite:dev",
  "lint": "eslint --ignore-path .gitignore --cache --cache-location ./node_modules/.cache/eslint .",
  "start": "wrangler pages dev ./build/client",
  "typecheck": "tsc",
  "typegen": "wrangler types",
  "preview": "npm run build && wrangler pages dev",
  "cf-typegen": "wrangler types",
  "local-seed": "./execute_seeds.sh",
  "local-migrate": "npx wrangler d1 migrations apply todo-cloudflare-d1 --local",
  "local-migrate-fresh": "npx wrangler d1 execute todo-cloudflare-d1 --local --file ./seeds/drop_tables.sql",
  "local-migrate-reset": "npm run local-migrate-fresh && npm run local-migrate",
  "local-migrate-reset-and-seed": "npm run local-migrate-reset && npm run local-seed",
  "remote-migrate": "npx wrangler d1 migrations apply todo-cloudflare-d1 --remote"
},
```
Remix Prismaの組み合わせでCloudFlare D1にマイグレーションするときのコマンドをnpm run 〇〇で実行できるようにする

## 概要

ローカルのD1へのマイグレーションコマンドが`npx wrangler d1 migrations apply BD名 --local`と長いのでnpmコマンドで実行できるようにする。

## 前提

下記の内容を実施し、マイグレーションができるようになっていること。

https://qiita.com/miriwo/items/d67c25fde2584110eb69

## 方法

1. package.jsonのscriptsに下記の内容を追加し`npm run local-migration`でローカルのマイグレーションが実行できるように設定

    ```package.json
    {
      "scripts": {
        "local-migrate": "npx wrangler d1 migrations apply DB名 --local"
      }
    }
    ```

1. package.jsonのscriptsに下記の内容を追加し`npm run remote-migration`で実際のCloudFlare上のD1のマイグレーションが実行できるように設定

    ```package.json
    {
      "scripts": {
        "remote-migrate": "npx wrangler d1 migrations apply DB名 --remote"
      }
    }
    ```
CloudFlareにデプロイするためのRemixプロジェクトに追加したテーブルにデータを入れるseedファイルを作って使ってみる

## 概要

下記の記事で作成したtask_category_mastersテーブルにデータを入れるseedファイルを作って実際に動かし、データが入ることを確認してみる。

https://qiita.com/miriwo/items/d67c25fde2584110eb69

## 前提

- CloudFlare上のD1データベース名は「todo-cloudflare-d1」とする。よってwrangler.tomlでdatabase_nameが`todo-cloudflare-d1`と指定されているものとする。

## 方法

1. 下記を実行してプロジェクトルートに`seeds`ディレクトリを作成

    ```sh
    mkdir seeds
    ```

1. 下記を実行して`seeds`ディレクトリ直下に`task_category_masters_seed.sql`を作成

    ```sh
    touch seeds/task_category_masters_seed.sql
    ```

1. `seeds/task_category_masters_seed.sql`を下記の様に記載

    ```seeds/task_category_masters_seed.sql
    -- InsertTable
    INSERT INTO task_category_masters (name) VALUES ('Work');
    INSERT INTO task_category_masters (name) VALUES ('Study');
    INSERT INTO task_category_masters (name) VALUES ('Other');
    ```

1. 下記を実行して`seeds/task_category_masters_seed.sql`を実行

    ```sh
    npx wrangler d1 execute todo-cloudflare-d1 --file ./seeds/task_category_masters.sql
    ```

1. table plusなどでローカルのD1（.wrangler/stage/v3/d1/miniflare-D1DatabaseObject直下の.sqliteファイルを指定）を確認し、下記の様にデータが入っていることを確認

    ![CleanShot 2024-06-14 at 01.34.53@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/f1d9e15e-469f-110e-938b-6fb09a02a05f.png)

1. ここまでこれれば基本は完了

## まとめてseedを実行するコマンドを作成

1. 下記を実行してプロジェクトルートに`execute_seeds.sh`というbashのスクリプトファイルを作成

    ```sh
    touch execute_seeds.sh
    ```

1. `execute_seeds.sh`を下記のように記載

    ```execute_seeds.sh
    #!/bin/bash
    
    # SQLファイルのリスト
    sql_files=(
        # NOTE: seedファイルを追加したらこちらにも追加
        "./seeds/task_category_masters_seed.sql"
    )
    
    # 各SQLファイルを実行
    for file in "${sql_files[@]}"; do
        npx wrangler d1 execute todo-cloudflare-d1 --local --file "$file"
    done
    ```

1. 下記を実行して`seeds/execute_seeds.sh`に実行権限付与

    ```sh
    chmod +x execute_seeds.sh
    ```

1. package.jsonのscriptsに下記のようにseedコマンドを追加し、`execute_seeds.sh`の実行を設定

    ```package.json
    {
      "scripts": {
        "seed": "./execute_seeds.sh"
      }
    }
    ```

1. 実行する前にtask_category_mastersテーブルの中身を削除し、空になっていることを確認
1. 下記を実行してtask_category_mastersテーブルにseedで指定した中身が記載されることを確認
Azure DevOpsのパイプラインからContainerAppsをデプロイしたメモ

## 概要

[前回](https://qiita.com/hibohiboo/items/d7c5a0177cd2f13e71a2)はローカルからのデプロイをした。
今回はパイプラインを通したデプロイを行う。


[Azure Pipelines から Azure Container Apps にデプロイする](https://learn.microsoft.com/ja-jp/azure/container-apps/azure-pipelines)に従う。


## マネージドIDの作成

```
#!/bin/bash


az containerapp identity assign \
  --name test-container-1 \
  --resource-group bicep-test-rg \
  --system-assigned \
  --output tsv
```


```
piyopiyo-0000-0000-0000-bd62ce015a3f    b990eb0b-ab75-4423-8ae2-4837dd052dd2    SystemAssigned
```

```sh:assignment.sh
#!/bin/bash

ACR_NAME="acrhogehoge" 
ACR_ID=$(az acr show --name $ACR_NAME --query id --output tsv)

az role assignment create \
  --assignee piyopiyo-0000-0000-0000-bd62ce015a3f  \
  --role AcrPull \
  --scope $ACR_ID
  ```

  ```
  az containerapp registry set \
  --name test-container-1 \
  --resource-group bicep-test-rg \
  --server acrhogehoge.azurecr.io \
  --identity system
  ```

  ## Azure DevOpsサービス接続を作成

  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/a7e1e632-6a86-e3ff-6be3-08da030c0a36.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/62268a77-991d-7517-7b87-97ba1629113a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/1a0761d4-ad0b-cc18-59d5-2d26104759a6.png)

## パイプラインからデプロイする
手順の通りに進めたら、下記エラーとなった。

```
##[error]Error Code: [1]
##[error]Error: Unable to create runnable application image using Oryx++ Builder.
```

原因は、手順のソースと別のソースを使っていたため、`appSourcePath`にDockerfileのないsrcフォルダを指定していた('$(Build.SourcesDirectory)/src`)こと。

> タスクでは、appSourcePath 内の Dockerfile を使用してコンテナー イメージがビルドされます。 Dockerfile が見つからない場合、タスクは、appSourcePath 内のソース コードからコンテナー イメージをビルドすることを試みます。

下記に修正したら動いた。


```yaml
trigger:
  branches:
    include:
      - main

pool:
  vmImage: ubuntu-latest

steps:
  - task: AzureContainerApps@1
    inputs:
      appSourcePath: '$(Build.SourcesDirectory)'
      azureSubscription: 'my-subscription-service-connection'
      acrName: 'acrhogehoge'
      containerAppName: 'test-container-1'
      resourceGroup: 'bicep-test-rg'

```

デプロイし、Functionsが更新されたことを確認できた。

なお、このときにACRにPUSHされ、コンテナアプリで指定されるイメージの名前は下記のようなものになる。

最後の`185.20240613.4`はAzure DevOpsのパイプラインが提供するビルド番号

```
acrhogehoge.azurecr.io/ado-task/container-app:185.20240613.4
```
複数の SARIF ファイルを統合する

# 経緯

Kotlin 言語で Android アプリ開発をしています。こちらの文献を参考に静的解析ツールの [detekt](https://detekt.dev/) を導入しました。

https://medium.com/@emrekoc/detekt-static-code-analyzer-for-android-c4c9bfd42a8c

これにより Gradle のタスク実行だけで静的解析ができて、レポートも出力できるようにしました。

```sh
./gradlew deteKt
```

[レポート形式](https://detekt.dev/docs/introduction/reporting/)は HTML や XML がありますが、今回は標準フォーマットと称される [SARIF](https://sarifweb.azurewebsites.net/) を使うことにしました。

さらに検出された Issue を GitHub のプルリクページにコメントするために、[reviewdog](https://github.com/reviewdog/reviewdog) を導入しました。CI で reviewdog コマンドにレポートファイルの中身を標準入力すると GitHub のプルリクページに投稿してくれます。

```sh
reviewdog -f=sarif -name="detekt" -reporter=github-pr-review < app/build/reports/detekt/detekt.sarif 
```

![スクリーンショット 2024-06-14 1.10.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334798/e75c687b-c1f3-8dab-4d92-64a88c2f24f6.png)


しかしこのプロジェクトはマルチモジュールなので複数のレポートファイルが出力されます。

```sh
find . -type f -name detekt.sarif 
```

```
./common/build/reports/detekt/detekt.sarif
./feature/home/build/reports/detekt/detekt.sarif
./androidApp/build/reports/detekt/detekt.sarif
./data/remote/build/reports/detekt/detekt.sarif
```

このままでは reviewdog コマンドに入力できないです。よって複数の SARIF ファイルを1ファイルに統合する方法を紹介します。

# 複数の SARIF ファイルを1つのファイルに統合する方法

マイクロソフト社が [sarif-multitool](https://github.com/microsoft/sarif-sdk/blob/main/docs/multitool-usage.md) というコマンドラインツールを OSS でリリースしています。[nodejs](https://nodejs.org/) で作られているので [npx コマンド](https://docs.npmjs.com/cli/v10/commands/npx)で動かせます。

それを find コマンドと合わせて使い、このようなコマンドで複数の SARIF ファイルを1つのファイルに統合できます。

```sh
find . -type f -name detekt.sarif -exec npx @microsoft/sarif-multitool merge {} +
```

`merged.sarif` というファイルが作られるので、それを標準入力で reviewdog コマンドに渡せば良いです。

```sh
reviewdog -f=sarif -name="detekt" -reporter=github-pr-review < merged.sarif
```

# 補足

Gradle でなく [jar ファイルをダウンロードして、それを実行する場合](https://github.com/detekt/detekt?tab=readme-ov-file#with-the-command-line-interface)は、マルチモジュールプロジェクトでもレポートファイルは1つになります。

find コマンドの　`-exec` と `{} +` については、こちらの記事が参考になります。

https://qiita.com/ironsand/items/0aed2ffca295706cab69
GithubActionsでさくらVPSへ自動デプロイ

# はじめに
これはさくらVPSのサーバーに自分のプロダクトを自動デプロイする手順の備忘録です。

# 手順
## SSH鍵の生成
`.ssh/`以下の適当なディレクトリに移動後、以下のコマンドを実行。
カレントディレクトリに作成されるため、必ずcdすること。
`ssh-keygen -t rsa -b 4096 -f id_rsa -C [メールアドレス]
`

その後、/path/to/id_rsa.pubを.ssh/authorized_keysに追記。


## Deploy keysへの登録
RSA公開鍵の登録。
さっき作ったid_rsa.pubとか。

## GithubへのSecretの登録
Github ActionsからさくらVPSへのデプロイに必要な項目を登録する。
- SERVER_DEPLOY_DIR
ディレクトリへのパス。操作したいとこ
- SERVER_HOST
VPSのホスト名
- SERVER_USERNAME
- SSH_PORT
基本的に22
- RSA秘密鍵
さっき作ったid_rsaとか。

## workflowを書く
githubのactionsからymlの作成。適当な名前でヨシ。
中身は大体こんな感じ。
```yml
name: CI

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Deploy
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USERNAME }}
          port: ${{ secrets.SSH_PORT }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          passphrase: ${{ secrets.SSH_PASS }}
          script: |
            cd ${{ secrets.SERVER_DEPLOY_DIR }}
            git pull origin main
            docker compose restart
```

# おわりに
多分これでできるようになる。
自分用の備忘録なので適当ですがこんなところで。
Dockerで簡単なAPIサーバ(Go)を立てる

## 前提
main.goファイル、go.mod , go.sumファイルが同階層にある前提です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821214/76962e7d-7264-dfb5-b545-9ea037268017.png)

以下を実施した後だとやりやすいです。

https://qiita.com/konnbu/items/76b977f715a13ec3bece

## Dockerfile 作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821214/2d225c90-d7bb-78f4-3a50-952198dbee13.png)

main.goと同じ階層に作成しています。

```
# FROM --> DocketHubからpullしてくるベースなるイメージの指定
# WORKDIR --> コンテナ起動後の作業ディレクトリ
# CMD --> CMDに記述した内容はコンテナを起動させた時に実行される

# goバージョン
FROM golang:1.22.1-alpine
# アップデートとgitのインストール
RUN apk update && apk add git
# ワーキングディレクトリの設定
WORKDIR /go/src/github.com/boiler-plate
# ホストのファイルをコンテナの作業ディレクトリに移行
COPY . .
# 依存関係のインストール
RUN go mod download
# goimports のインストール
RUN go install golang.org/x/tools/cmd/goimports@latest
# アプリケーションのビルド
RUN go build -o main .
# ポートを公開
EXPOSE 1323
# アプリケーションの実行
CMD ["./main"]
```

少しハマったのでメモ。
```
# アプリケーションのビルド
RUN go build -o main .
```
で終わり、ではダメで、
```
# ポートを公開
EXPOSE 1323
# アプリケーションの実行
CMD ["./main"]
```
もちゃんと書く必要があるらしいです。

## image作成

Dockerファイルを元にイメージを作成します。
``docker build -t sample-piyo-image-go:latest .``
たまにtimeoutで失敗しますが、再実行するとなおることも。
※ -t ... イメージに名前とタグをつけるオプション

イメージが作成されていることを確認するには以下のコマンドで。
``docker image ls``


## コンテナ起動

Dockerコンテナを起動します。
``docker run -di -p 1323:1323 --name=[CONTAINER_NAME] [IMAGE_NAME]``
ex ``docker run -di -p 1323:1323 --name=test-go-piyo sample-piyo-image-go``

※このport(1323:1323)はmainのportと同じ値である必要があります。
　mainでリスナーとして定義したportと、立ち上げたコンテナのportは別で動くため一致させる必要がある、ということです。

コンテナの起動確認は以下のコマンドで行います。
``docker ps -a``

※もし立ち上がらない場合は以下のコマンドでログを確認できます。
``docker logs [CONTAINER_NAME]``

## API実行
``curl http://localhost:1323/``を打鍵してみます。※ポート番号は任意
想定通りのレスポンス(今回は`Hello,World！`)が返されればOK。

ログは
``docker logs [CONTAINER_NAME]``
から確認できます。

## コンテナの中に入る

Dockerコンテナの中へ入るには以下のコマンドで実行します。
``docker exec -it [CONTAINER_NAME] /bin/sh``

※exitで出られます。

## その他

port確認は以下のコマンドから。
``docker container ls``

## 参考
https://zenn.dev/yusuke49/articles/9ed37838861b1d
基本的なuseContextを使用した状態管理

## アジェンダ
`useContext`を使用して、状態管理をシンプルに行う方法について解説します。`useContext`は、Reactの「バケツリレー」問題を解決し、深い階層にあるコンポーネント間でも簡単にデータ共有を可能にします。

## 基本機能
### `createContext`: デフォルト値の設定
まずは、共有したいデータやメソッドを`createContext`で作成します。ここではデフォルト値を設定します。

```tsx
import { createContext } from "react";

export const CountContext = createContext({
  count: 0,
  setCount: () => {},
});
```

### `Provider`: コンテキストの値を提供
次に、作成したコンテキストを使用して、`Provider`を作成します。これにより、子コンポーネントに状態を共有できます。

```tsx
import { useState, ReactNode } from "react";
import { CountContext } from "./CountContext";

const CountProvider = ({ children }: { children: ReactNode }) => {
  const [count, setCount] = useState(0);

  return (
    <CountContext.Provider value={{ count, setCount }}>
      {children}
    </CountContext.Provider>
  );
};

export default CountProvider;
```

### `useContext`: コンテキストの利用
状態を使用したいコンポーネントでは、`useContext`を使います。

```tsx
import { useContext } from "react";
import { CountContext } from "./CountContext";

const CountDisplay = () => {
  const { count } = useContext(CountContext);
  
  return <p>現在のカウント: {count}</p>;
};
```

## useStateを使った動的な状態管理
次に、`useState`でコンテキストの状態を動的に管理する例です。

### 手順1: コンテキストの作成
まず、コンテキストを作成し、初期値を設定します。

```tsx
import { createContext } from "react";

export const HogeContext = createContext({
  value: "",
  setValue: (value: string) => {},
});
```

### 手順2: Providerの作成
`useState`で状態を管理し、その値を`Provider`で渡します。

```tsx
import { useState, ReactNode } from "react";
import { HogeContext } from "./HogeContext";

const HogeProvider = ({ children }: { children: ReactNode }) => {
  const [value, setValue] = useState("hoge");

  return (
    <HogeContext.Provider value={{ value, setValue }}>
      {children}
    </HogeContext.Provider>
  );
};

export default HogeProvider;
```

### 手順3: コンテキストの使用
`useContext`を使って値と更新関数を取得し、UIに反映させます。

```tsx
import { useContext } from "react";
import { HogeContext } from "./HogeContext";

const Hoge = () => {
  const { value, setValue } = useContext(HogeContext);

  return (
    <>
      <p>{value}</p>
      <button onClick={() => setValue("poge")}>Change Value</button>
    </>
  );
};
```

### 手順4: Providerでラップする
必要なコンポーネントを`HogeProvider`でラップします。

```tsx
import ReactDOM from "react-dom";
import HogeProvider from "./HogeProvider";
import Hoge from "./Hoge";

ReactDOM.render(
  <HogeProvider>
    <Hoge />
  </HogeProvider>,
  document.getElementById("root")
);
```

## まとめ
- `createContext`: デフォルト値を設定
- `Provider`: コンテキストを提供
- `useContext`: コンテキストを利用

## 参考
- [useContext – React](https://ja.react.dev/reference/react/useContext)
- [【入門】useContextを5分で理解する - らくらくエンジニア](https://rakuraku-engineer.com/posts/react-usecontext/)
【備忘録】WSL2にanaconda3をインストールしてcondaを使えるようにするまで

　自分がWSL2にAnaconda環境を設定した際の作業の流れを備忘録的に記録していますので、誰かの参考になれば幸いです。今回の作業は以下の環境で実行しています。
 - Windows11 Pro
 - WSL2 (Ubuntu)

# Anaconda3をインストールする
### 1.公式サイトからインストーラのダウンロード
　公式サイト ([https://www.anaconda.com/download/success](https://www.anaconda.com/download/success)) に行って、Linux用のインストーラをダウンロードします。この記事を書いている、2024.6.14時点では「Python 3.11 64-Bit (x86) Installer(997.2M)」がそれにあたります。
 
### 2.bashを用いてインストーラを実行
　先程ダウンロードしたインストーラをターミナル上で実行します。以下はインストーラがDownloadフォルダ直下にあるという想定ですので、適宜パスは書き換えてください。またインストーラの名称も変わっている可能性があるので、その際はインストーラ名を自分がダウンロードしたものと一致させてください。
```terminal
$bash /mnt/c/Users/(user_name)/Downloads/Anaconda3-2024.02-1-Linux-x86_64.sh
```
しばらく待つとインストールが開始され、その後利用規約の同意を経て終了となります。

# condaを使えるようにする
　他の方の記事を見ているとインストールが終わった時点でcondaが使えるようになっている方もいらっしゃるようですが、私の環境では上記の作業を終えた時点では、
```terminal
$conda --version
conda: command not found
```
というように、condaがコマンドとして認識されていませんでした。
　これを解消するために、パスを通します。やり方は以下のコマンドをターミナル上で実行するだけです。
 ```terminal
 $export PATH="~/anaconda3/bin:$PATH"
 ```
 これでcondaが使えるようになりましたが、その後に
 ```terminal
 $conda init
 ```
 を実行することで、base環境をactivateすることができるようになります。
 　以上でcondaをWSL上で使えるようになりました。ここまで読んでいただいてありがとうございました。