OmniAICreator/Qiita-1.07M huggingface dataset:
MySQLの初歩的な操作方法

## 目次
- [MySQLを動かす](#mysqlを動かす)
- [MySQLを使う](#mysqlを使う)
  - [データベース](#データベース)
  - [ユーザー](#ユーザー)
  - [テーブル](#テーブル)
  - [データ](#データ)



# MySQLを動かす

### 起動
```
mysql.server start
```
### 停止
```
mysql.server stop
```
<br>
<br>

# MySQLを使う


### MySQLにログイン
```
mysql -u root -p     
```
<br>


# データベース

### データベースを作成
```
CREATE DATABASE first_db;
```
:::note
次のような表示が出ればデータベースができた合図です。
`Query OK, 1 row affected`
:::
<br>

### データベースの表示・指定・確認
```
SHOW DATABASES;
```
<br>

### MySQLクライアントを使用してデータベースを選択

次のようにUSEコマンドを使用してデータベースを選択できます。

```
USE database_name;
```
<br>

::: note
### 選択中のデータベースを確認する
```
SELECT DATABASE();
```
:::

<br>

### データベースの削除
1. データベースを選択します。削除するデータベースを選択します。
    ```
    USE your_database_name;
    ```
    your_database_nameは削除したいデータベースの名前です。

1. データベースを削除します。
    ```
    DROP DATABASE your_database_name;
    ```
    your_database_nameは削除したいデータベースの名前です。実行すると、データベースが削除されます。



<br>
<br>

# ユーザー



### 新しいユーザーを作成する
以下は、名前とパスワードを指定して、ホストをlocalhostに設定する例です：

```
CREATE USER 'ユーザー名'@'localhost' IDENTIFIED BY 'パスワード';
```
<details><summary>このコマンドの各部分についての説明</summary>

1. CREATE USER: ユーザーを作成するためのキーワードです。

1. 'ユーザー名': 新しいユーザーの名前をここに指定します。単引用符または二重引用符で囲むことが一般的です。

1. @'localhost': ユーザーが接続できるホストを指定します。localhostを指定すると、このユーザーはローカルマシンからの接続のみを許可します。他のホストからの接続を許可する場合は、ホスト名またはIPアドレスを指定します。

1. IDENTIFIED BY 'パスワード': ユーザーのパスワードを指定します。シングルクォートまたはダブルクォートで囲むことが一般的です。
</details>


### ユーザーの一覧を表示
```
SELECT user, host FROM mysql.user;
```
<br>

### ユーザーを削除
```
DROP USER 'ユーザー名'@'ホスト名';
```
<br>

### 権限の付与
新しいユーザーにすべてのデータベースとテーブルへのアクセス権限を付与します。
以下のコマンドを実行して、新しいユーザーに全権限を与えます。

```
GRANT ALL PRIVILEGES ON *.* TO 'myuser'@'localhost';
```
:::note warn
#### 権限を付与した後はロードする

`FLUSH PRIVILEGES;`

:::

# テーブル



### テーブルを作成する
```
CREATE TABLE (テーブル名)
    (col_name data_type, ...);
```
::: note warn
作りたいデータベースを選択しておく
```
USE database_name;
```
:::

<br>

### テーブル一覧を表示

```
SHOW TABLES;
```
<br>

### カラムを追加
```
ALTER TABLE (テーブル名)
ADD (追加したいカラム名) (データ型);
```
<br>

### カラムの一覧を表示
```
SHOW COLUMNS FROM (テーブル名);
```
<br>

### カラムを削除
```
ALTER TABLE (テーブル名)
DROP COLUMN (削除したいカラム名);
```
<br>

### テーブルを削除
```
DROP TABLE books;
```
:::note
確認　`SHOW TABLES;`
:::

<br>

# データ



### データの挿入

```
INSERT INTO (テーブル名) (挿入するカラムのリスト)
VALUES (各カラムに挿入するデータの値);
```
<br>

### データを表示
```
SELECT * FROM (テーブル名);
```

<br>

### データの削除
```
DELETE FROM (テーブル名)
WHERE (カラム名) = '値';
```
WHEREの後のカラム名と一致する値を持つ行のみを削除します。
<br>
<details><summary>データの全削除</summary>

```
DELETE FROM (テーブル名);
```

</details>
工数管理の方法について

## はじめに
普段UiPathの記事を書いていますが、今回は簡単に工数を管理してくれる方法がないか考えてExcelVBAで工数管理表を作成し、そのナレッジを書くことにしました。
ExcelVBAを使用したことがある方にわかる内容になっています。
またこれを作成しようとした意図についても書きます。
## 工数管理の大変さ
普段、私はサクラエディタでタスク管理をしています。タスク管理は業務中に何回も見ています。具体的には下記のようにしています。

:::note info
**・業務開始時に残タスクの優先度を確認する。
・業務中に完了したものがあれば、その時に「完了」と「かかった工数時間」を記載する。
・業務中に発生した緊急のタスクや追加タスクがあれば、残タスクと比較して優先度を確認する。
・業務終了30分前に残タスクの優先度を確認する。**
:::

上記の方法でうまく管理できていました。
しかし、先月1人で約20本のロボットの改修＋αのタスクを行い、常に改修作業でタスクの優先度は確認できたものの、工数時間の管理ができなかったです。忙しいときにも「簡単に工数を管理できたらな」と考えました。
## ExcelVBAで工数管理
UiPath以外にもExcelVBAのスキルがあったので、それで管理してみようと考えました。
UiPathで管理しようと考えましたが、結局Excelのみで管理するので、ExcelVBAの方が手間がないと考えました。
## Excelのフォーマット
**実行ボタンがあるあるシート↓↓**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327229/7003d91a-75bd-b148-9ac4-f76b980041be.png)
**実行前の工数管理表↓↓**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327229/e7198704-d0f2-13ba-3f8c-b410835a29be.png)
**実行後の工数管理表↓↓**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327229/09438a39-2ebd-ca7c-2cd2-3a40fab3e9f8.png)

## 実際のコード
実行ボタンの作成方法がわかるのであれば、このコードのコピーと工数管理表のヘッダでExcelを作成してもらえば、使用できると思います。久しぶりに書いたので綺麗さなどは大目に見てください！
```
Dim IX_最終行   As Long
Dim IX_行数     As Long
Dim IX_年月     As String

Private Sub 工数計算_Click()

    IX_年月 = Format(Date, "yyyym")
    
    With Worksheets(IX_年月)
        
        IX_最終行 = .Cells(1, 2).End(xlDown).Row
        IX_行数 = 2
        
        For IX_行数 = 2 To IX_最終行
            .Cells(IX_行数, 3) = .Cells(IX_行数, 7) + .Cells(IX_行数, 3)
            
            If .Cells(IX_行数, 6) <> "" Then
                .Cells(IX_行数, 4) = "完了"
            End If
            
            .Cells(IX_行数, 7).Clear
            
            If .Cells(IX_行数, 4) = "完了" Then
                .Range(.Cells(IX_行数, 1), .Cells(IX_行数, 10)).Interior.Color = RGB(200, 200, 200)
            End If
        
            If .Cells(IX_行数, 2) <> "" Then
                .Cells(IX_行数, 1) = IX_行数 - 1
            End If
        Next
        
    End With

End Sub
```
## さいごに
久しぶりにコードを書いて楽しかったです！！
これを用いてからは日々の工数管理が楽になりました。一方でこれを用いて月次報告をすぐにできるようにしたいと考えています。
バックエンドをGoからRailsに切り替えたお話

# はじめに
今年のカレンダーはとある会社のとあるチームで活動した1年間を振り返っていきます

背景はこちらに記載しています

# バックエンドをGoからRailsに切り替えたお話
## やったこと
環境構築の記事を以前投稿しています。

https://qiita.com/does_not_exist/items/19c35639e466844e8b0e

https://qiita.com/does_not_exist/items/23a70dab286ed146b05f

https://qiita.com/does_not_exist/items/b79b3fd51ea6ef39df23

## 気づいたこと
環境構築はGoよりRailsの方が少し早くできたような気がします。
Rails側でよしなに設定してくれる箇所が多いからだと思います。Goはポインタや構造体という概念があるので理解に時間がかかったりしました。コードの書きやすさ、可読性でいえばGoの方が良いのかなという感触でした。

# おわりに
RailsもGoもさらに触れていき、状況に応じて技術選択できるようになりたいです。
環境変数を設定してみた

# 概要
Javascript系統のWebサーバーで環境変数を設定してみた.
自分の環境はNextJSを使用していて,コードを修正すると自動でコンパイルが走る.

しかし,環境変数のホットフィックスが実行されないのでログを残してみる.

# 環境変数の設定方法
一般的な設定方法はルートディレクトリ(node_modulesとかがあるディレクトリ)に`.env`を配置する.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1505183/206aa24b-06a3-061e-b78d-6e83558707ae.png)

そして,中身はこんな感じ,
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1505183/1149ea7d-b18d-260b-1cf4-988e5c8f8675.png)
コメントは＃を用いる.
環境変数名は基本大文字
データは"ダブルクオーテーション"で囲んでも囲まなくてもいいが,
URLとかに#が入ってもいいように囲んでる.

# 環境変数の使用
`xxx.js`ファイルや`xxx.ts`ファイル`xxx.tsx`ファイルでは,`process.env`を使用して環境変数を取得する.  
試しに以下のように作成してみた.  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1505183/70213a81-8f67-dde9-a8c9-c0054d49a016.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1505183/473aa357-94f9-e885-6cdc-7dfffc655637.png)


うまくいけば画面に
```
env test!!
env : ENV_TEST_CONTEXT
```
と表示される予定
失敗したら
```
env test!!
env : 環境変数が割り当てられてないみたい
```
と表示される.


NextJSの仕様上,編集するとこんなサーバーログが流れる.  
これはホットフィックスと呼ばれるもので,編集後,自動でビルドしなおしてくれる.  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1505183/21ee4206-8e10-9eda-2455-e08feb2d61e1.png)
<details><summary>どうやってログを出してるか詳細</summary>
自分の環境ではDockerを用いてReactサーバーを立てている.
サーバーログは`docker logs -f nextjs`で取得している.
nextjs部分はReactサーバーのコンテナ名なので良しなに変更すること.
</details>

## ページを見に行ってみた結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1505183/72fe7748-7cf8-2da8-8069-e88522fb4885.png)

## どうして表示されないのか？
実はホットフィックスでは環境変数がビルドされないからである.  
したがって意図的にビルドしなおす必要がある.

今回はDockerのコンテナ再起動という方法でやってみた.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1505183/95b92d75-0057-84c6-d0b7-fb26730a2ec4.png)
サーバーログの確認
`/app/.env` が読み込まれているのがわかる.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1505183/33ca444d-ba72-b7cb-e877-68fa43ffc95f.png)
ページの確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1505183/5f8fd98d-30c7-837a-4247-865e4b650636.png)

# 終わりに
サービスが完成しても,接続先等は変更されることが多々ある.
その時に,ソースコードを編集するのではなく,環境変数を変えればいいよね.
というのが,環境変数の目的.
うまいこと使えるようしたい.

# Gitに保存するときの注意点
環境変数は秘密にすべきものを入れることがある.
例えばDatabaseのパスワードであったり,APIKEYであったり,
そういったものはGit等で他人と共有してはいけない.
しかし,`.env`が無いと不便なので,以下のファイル作成を推奨したい.

ファイル名は `.env.sample`
内容は以下のように,変数名だけ指定しておきます.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1505183/b05d3891-802f-8aaf-037f-6728a35cab10.png)

それともう一つ,Gitで管理するのであれば,`.env`ファイルを`.gitignore`に追加しておくこと！
Edge メニュー バーから Copilot Icon を一括で非表示とする方法

# 変更履歴
"Bing Chat" から "Copilot Icon" に表記を修正 (2024/02/01)。

# これは何？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48302/280085aa-c705-a174-089c-bc9b258f82e0.png)
　　　　　↑これを Policy にて非表示にする方法です。

なお、Edge の Copilot Icon を無効化するだけなので、Bing のページでの利用制限はこの方法ではできません。
~~通信先を調べてブロックするとかいう手を取ればごにょごにょ…~~ 

# 設定方法
アイコン及び機能の実体は拡張機能なので、以下の2つの拡張機能 ID を 
[ExtensionInstallBlocklist](https://learn.microsoft.com/ja-jp/deployedge/microsoft-edge-policies#extensioninstallblocklist) に設定するのみです。

・ofefcgjbeghpigppfmkologfjadafddi
・nkbndigcebkoaejohleckhekfmcecfja

# 補足
~~2023/11/09 時点(Edge Stable 119) の方法であり、恒常対策となるかは不明です。~~
2024/02/01 時点(Edge Stable 121) 時点でも有効であることを確認。
新技術と保守性

# はじめに
今年のカレンダーはとある会社のとあるチームで活動した1年間を振り返っていきます

## 登場人物
### Jさん：
昨年で転職。在籍時は社内に新しい風を巻き起こし、その影響度は今でも意志を受け継ぐ者がいるほど。

### ちいかわトミカさん：
先輩で頼りになる方。疲れたらちいかわトミカで遊んでいる？よくダジャレを言う。得意なダジャレは「今日言う共有事項はないです」

### くじらさん：
昨年で転職された元我がチームの上司。Dockerが大好きな方。

# 新技術と保守性
くじらさん：すみません！今Goで開発されていると思うのですが、今後を考慮してRailsに置き換えていただきたいです…

ちいかわトミカさん：Railsであれば対応にそんなに時間かからなさそうなのでいけそうじゃないですか？

私：ですね！やってみます！

---

大まかな流れとしてはDocker環境を一部変更し、データベースとの接続を確認、バックエンドを書き換えてフロントと疎通を確認して…という流れでした。
バックエンドを書き換える際はもちろんテスト駆動です。

https://qiita.com/does_not_exist/items/19c35639e466844e8b0e

https://qiita.com/does_not_exist/items/23a70dab286ed146b05f

これまでは4人チームでGoとTypeScriptを学びながらシステム開発をしていましたが、ひょんなことから1人で開発することになりました。今後のことを考えると、他チームから増員orプロジェクトの保留の判断をする必要がありました。当時はある程度システムが完成してしまっていたのでプロジェクトは継続、増員についてはバックエンドのみ各チームで主流なRailsに置き換えた後に補充することになりました。

他チームに新技術を伝承することができていれば違った状況になっていたのかなと思います。
振り返ってみるとそこまでの余裕はありませんでしたが…
この一件で新しいことを学んで開発することと、保守は表裏一体であることを痛感しました。

# おわりに
言語を置き換える経験は初めてでしたが良い経験になったと思います。
新技術で開発中であってもToDoアプリのハンズオン程度の勉強会ならできたと思うので次はよしなに立ち回っていきたいです。
UIBarButtonItem内の押せないはずのボタンが押せてしまう

# 解決策
UIButtonをUIBarButtonItemに変換した後、isEnabledをfalseにすればちゃんと押せなくなってくれた。

```swift:SampleViewController.swift
let barButtonItem = UIBarButtonItem(customView: button)
button.isEnabled = false
navigationItem.rightBarButtonItem = barButtonItem
```

# 原因
isEnabledがfalseのUIButton(押せないボタン)をUIBarButtonItemに変換しても、そのボタンのisEnabledは自動的にtrueになってしまうようだ。

以下はボタンが押せてしまうコード例
```swift:SampleViewController.swift
let button = UIButton()
button.setTitle("ボタン", for: .normal)
button.addTarget(self, action: #selector(tappedButton), for: .touchUpInside)
button.isEnabled = false
            
let barButtonItem = UIBarButtonItem(customView: button) // button.isEnabled = trueに自動で書き換わってしまう
navigationItem.rightBarButtonItem = barButtonItem
```
【Django備忘録】django-environを使って機密情報を別ファイルで管理する

# はじめに
これまでQiitaは眺めるだけで記事を書くことをしてきませんでしたが、備忘録のため、そして自分の認識が間違っていた場合に集合知によって殴られるため（？）、一念発起して記事を書いてみることにしました。願わくば同じような課題に突き当たっている方の助けとなりますように。

Django備忘録シリーズと称して今回は、SECRET_KEYをはじめとするGitにはちょっとcommitしづらい機密情報を別ファイルで管理する方法を書いていきます。

ここで紹介する実装は[Github](https://github.com/sho-gun/django-samples)で公開しています。以下、ディレクトリ構成は公開しているリポジトリに準拠するものとします。

https://github.com/sho-gun/django-samples

# 機密情報とは
本記事で触れているDjangoプロジェクトに限らず、一般的なプロジェクトには多かれ少なかれ機密情報が含まれていることが多いと思います。

Djangoプロジェクトの場合、大体以下の情報が機密情報となることが多いのではないでしょうか？

1. SECRET_KEY
1. データベースのホスト名、ユーザ名、パスワード等
1. 外部サービスのAPIキー等

これらの情報をうっかりGitHub等で公開してしまうと、不正アクセスによる情報漏洩の原因となったり、契約している外部サービスを勝手に第三者に使われて、課金額が恐ろしいことになったりします。

またこれらの情報は、開発環境、ステージング環境、本番環境でそれぞれ別の値としたいケースも多いです。（例：決済サービス[Stripe](https://stripe.com/)のテストキーと本番キー）

こういった機密情報をDjangoプロジェクトの実装から切り離して別ファイルで管理し、環境ごとの値の切り替えを簡単に実現してくれるのが**django-environ**です。

https://django-environ.readthedocs.io/en/latest/#

# django-environを使ってみる
Djangoプロジェクトの作成方法については、先人の知恵が調べればたくさん出てくるので、一旦割愛します。筆が乗ればいずれ自分でも書きます。

まずはインストールしないと始まらないので、pipでサクッと入れてしまいましょう。

```bash:bash
pip3 install django-environ
```

インストールできたら、次はsettings.pyに含まれている機密情報を別ファイルに書き出していきます。
プロジェクトのルート直下（sample_project/）に.envというファイルを作成しましょう。

**説明の都合上.envもGitHubに公開していますが、実際には絶対に公開してはいけません。.gitignoreに忘れずに追記しておきましょう。.envは絶対に公開してはいけません。**

.envの中身は、例えばこんな感じです。

```text:sample_project/.env
DEBUG=on
SECRET_KEY=django-insecure-_fm3))r6!#)^wxpv2r1*&gzj=wnhis!nb-u26fjlphj$e(a(%4
ALLOWED_HOSTS=localhost
```

別ファイルで管理したい機密情報を.envに書き出したら、最後にsettings.pyを編集します。
django-environをインポートして、settings.pyに記述されている各種機密情報を.envを参照した値に置き換えましょう。

```python:sample_project/sample_project/settings.py
# django-environを用いた環境変数の秘匿サンプル
# django-environをインポート
import os
import environ
from pathlib import Path

# envオブジェクトを作成
env = environ.Env(
    DEBUG = (bool, False)
)

# sample_project/.envを読み込み
# CAUTION: sample_project/.envは、実際のプロジェクトではGit管理内容に含めない！
BASE_DIR = Path(__file__).resolve().parent.parent
environ.Env.read_env(os.path.join(BASE_DIR, '.env'))

# 読み込んだ環境変数を設定
SECRET_KEY = env('SECRET_KEY')
DEBUG = env('DEBUG')
ALLOWED_HOSTS = env.list('ALLOWED_HOSTS')
```

サーバを起動してみて、正しく起動すれば設定は完了です。おめでとうございます！

# 環境ごとに設定値を切り替える
.envの内容を、環境ごとに変更しておくだけです。Git管理から外しているので、pullしても.envの内容は上書きされません。やったね！

# 結論
- 機密情報はGitに公開してはいけない
- 機密情報はGitに公開してはいけない
- 機密情報はGitに公開してはいけない
- 機密情報はGitに公開してはいけない
- 機密情報はGitに公開してはいけない
- 機密情報はGitに公開してはいけない
SVMを用いた決定的識別モデルについて

## はじめに

決定的識別モデルは、データを異なるクラスまたはカテゴリに分類するための重要なツールです。その中でも、サポートベクトルマシン（SVM）は非常に強力なアルゴリズムであり、多くの実世界の問題に適用できます。この記事では、SVMを使用して決定的識別モデルを構築する方法に焦点を当てます。

## SVMの基本

### SVMとは何か？

SVM（サポートベクトルマシン）は、機械学習の分野で広く使用される強力なアルゴリズムです。SVMは、データを異なるクラスに分類するための教師あり学習アルゴリズムであり、線形および非線形な問題の解決に使用できます。SVMは、データポイントの最適な境界（決定境界またはハイパープレーン）を見つけることを目指します。

決定境界（ハイパープレーン）は、次の数式で表現できます。
$$ \mathbf{w}^T\mathbf{x}=0 $$

ここで、  
- $\mathbf{w}$ は決定境界の法線ベクトル
- $\mathbf{x}$ はデータポイントの特徴ベクトル

SVMは、この決定境界を最適化し、クラス間のマージンを最大化することを目指します。マージンは、決定境界と最も近いサポートベクトルまでの距離を表します。

### SVMの仕組み

SVMの基本的なアイデアは、異なるクラスに属するデータポイントを分離するための最適な境界を見つけることです。この境界は、データから最も近いサポートベクトル（Support Vector）までの距離を最大化するように選択されます。

SVMは、線形SVMと非線形SVMの2つの主要なバリエーションがあり、問題の性質に応じて選択できます。線形SVMは線形分離可能な問題に適しており、非線形SVMは非線形な問題に対処できます。非線形SVMはカーネルトリックを使用して、非線形な関係を捉えることができます。

## SVMを用いた決定的識別
以下は線形SVMを利用して、2クラス分類を行うことを前提としています。

### SVMの損失関数
SVMの損失関数にL2正則化を追加した損失関数は以下の通りです。
$$E(\mathbf{w}) = |\mathbf{w}|^2 +C\sum_{i=1}^{N} \max(0, 1 - y_i(\mathbf{w} ^T\mathbf{x}_i ) $$ 

ここで、  
- $N$ はデータポイントの数
- $y_i$ は正例（+1）または負例（-1）のラベル
- $\mathbf{w}$ は重みベクトル
- $\mathbf{x}_i$ は特徴ベクトル
- $\lambda$ は正則化パラメータ（ラムダ）

この損失関数は、通常のヒンジ損失に加えて、正則化項が含まれています。正則化項は、重みベクトル $\mathbf{w}$ のノルム（L2ノルム）の二乗をペナルティとして追加し、過学習を抑制します。実際の学習ではSGDが用いられることが多く、この場合の損失関数は以下のようになります。
$$E(\mathbf{w}) = |\mathbf{w}|^2 +C\max(0, 1 - y_i(\mathbf{w} ^T\mathbf{x}_i ) $$ 
これを$\mathbf{w}$ に対して劣微分すると、以下のようになります。
$$
\frac{\partial E(\mathbf{w})}{\partial \mathbf{w}} =
\begin{cases}
2\mathbf{w}-Cy_i \mathbf{x}_i & \text{if } 1 - y_i(\mathbf{w}^T \mathbf{x}_i) > 0  
     & \text{otherwise  }
     2\mathbf{w}
 \end{cases}
$$
## SVMのパラメータの更新式

SVMのパラメータ $\mathbf{w}$ および $b$ の更新式は、確率的劣勾配降下法を使用して次のようになります。

- $\mathbf{w}$ の更新式
$$\mathbf{w'} ← \mathbf{w} - \alpha \nabla_{\mathbf{w}} E(\mathbf{w}) $$
- $\alpha$ は学習率（learning rate）で、更新ステップの大きさを調整します。
- $\nabla_{\mathbf{w}}$ は $\mathbf{w}$ に関する偏微分

正則化項により、重みベクトル $\mathbf{w}$ が小さく保たれ、過学習を防ぎます。


## 結言

SVMを用いた決定的識別モデルは、様々な分野で応用されており、優れた性能を発揮します。この記事では、SVMの基本的な原理から具体的なモデルの構築手順を説明しました。今回説明したSVMは線形分離が可能であることを前提としています。
RDSのCA入れ替えに伴うはまりどころ

# RDSのCA入れ替えに伴うはまりどころ
Amazon Linux 2など古いopensslのOSがある環境では、RDS等のCAを ecc384 にしてならない。接続障害となってしまう。

※もちろん、TLS/SSLでのRDS接続を行って`いない`環境では問題ありません。

## そのわけ
- Amazon Linux 2 の openssl は 1.0.2k、つまり TLSv1.2までしかサポートしていない
- RDS for MySQLのTLS/SSL対応初期値は TLSv1.2,TLSv1.3
- TLSv1.2 に対応していないCAを指定すると、設定値は補正されないが実際にはTLSv1.2が除外された挙動になる
- rds-ca-ecc384-g1/rds-ca-rsa4096-g1/rds-ca-rsa2048-g1 のうち、 rds-ca-ecc384-g1 はTLSv1.2非対応

CA を rds-ca-ecc384-g1 にすると暗黙のうちに TLSv1.2 が排除され、 TLSv1.3 専用となってしまう。
だがその警告が見当たらない。SQLで調べて見てもTLSv1.3専用に切り変わっている事が分からない。

## 対応策
+ OSをRocky Linux 8など、openssl 1.1以上のもので構築しなおす
+ CAを rds-ca-rsa4096-g1 または rds-ca-rsa2048-g1 に切り替える
1人で抱え込まずに頼ろう

# はじめに
今年のカレンダーはとある会社のとあるチームで活動した1年間を振り返っていきます

## 登場人物
### Jさん：
昨年で転職。在籍時は社内に新しい風を巻き起こし、その影響度は今でも意志を受け継ぐ者がいるほど。

### ちいかわトミカさん：
先輩で頼りになる方。疲れたらちいかわトミカで遊んでいる？よくダジャレを言う。得意なダジャレは「今日言う共有事項はないです」

# 1人で抱え込まずに頼ろう
私：今日が最終出社日ですか…

Jさん：はい！もし分からないことがあればいつでもLINEしてください！大歓迎です！

ちいかわトミカ：うお～～(泣) 寂しいので残ってください

Jさん：あとは任せました

ちいかわトミカ：僕たちは別の案件やらなくちゃいけなくなったので…あとは任せましたmake_testさん

私：うお～～(泣)

---

1人で新技術を学びながら開発すると、考える時間や調べる時間が多くなってしまい気づいたら沼にハマっていて時間が溶けていたということがありました。
今回はJさんの言葉に甘えて何度か相談に乗ってもらったり、ちいかわトミカさんにも雑談ベースで相談に乗ってもらいました。するとあっさり解決…なんてことがありました。
ちいかわトミカさんは私と同じく新技術を学びたてであるにもかかわらず「多分ここが怪しい気がする」の一言で解決…。戦ってきた場数が違うと経験による感でなんとかしてしまうんですね。


# おわりに
他の人が分からないような内容でも雑談ベースで相談することで自分の頭が整理できたり、運が良ければ解決できてしまうこともあるので、困ったら頼れるものは頼ってしまおうと思いました。
🚀 Windows/VSCode向けStarship導入メモ

公式に丁寧な[導入マニュアル](https://starship.rs/ja-JP/guide/)があるんですが、**漏れてる作業内容が多く**、毎回ググってるのでまとめます。

# 1. Nerd Fontを導入
Nerd Fontをインストールしターミナルに適用する必要があります。面倒臭がって適用しないと文字化けしたりして見栄えがよろしくないので入れましょう。

## 1-1. フォントをダウンロードする
バリエーションがたくさんあり面食らいますが、こだわりがなければ導入マニュアルの例にある[FiraCode Nerd Font](https://www.nerdfonts.com/font-downloads)でいいかと。

## 1-2. フォントをインストールする
Windowsのタスクバーの検索から「フォント」とか打ち込むと「フォント設定」が出てくるので開き、展開したZipファイルの中身をドラッグアンドドロップします。

## 1-3. ターミナルの使用フォントを変更する
「WindowsだとVSCodeのターミナルってPowershellだから、Powershellの設定を弄ればVSCodeのターミナルにも適用されるよね」と思ったんですが、実はVSCode側で上書きしてて適用されなかったような気が……。

 `Ctrl + Shift + P`でコマンドパレットを開き、`setting.json`と打ち込むと「基本設定：ユーザー設定を開く(JSON)」というコマンドが候補に上がるので開きます。
JSONファイルが表示されるので、
 ```json
	"terminal.integrated.fontFamily": "FiraCode Nerd Font Mono",
 ```
という一文を追加します。ちなみにMonoフォントじゃないとターミナルのフォントとして使えないようで、小さな警告ウィンドウが表示されて無効化されます。

# 2. Starshipをインストールする
普通にインストーラーを使うのもよし、記載の通りパッケージマネージャーで入れるのもよし。

# 3. Powershell起動時にStarshipを呼び出すように設定する。
Powershellの環境設定ファイルに書き込む必要があります。ターミナルで`$PROFILE`を打ち込むと、存在する場合は絶対パスが表示されるのでそのまま開きます。
無い場合はエラーとなるので、

```shell
New-Item $profile -force -type file
```
を実行すると、デフォルトの位置に`Microsoft.PowerShell_profile.ps1`が生成されます。
同じく開いてもらい、

```shell
Invoke-Expression (&starship init powershell)
```
と1行記載するだけでPowershellを起動時にStarshipが適用されるはずです。
適当にlsコマンド打つとか、Gitリポジトリのあるフォルダ開くとかして、カラフルになってたら成功です。もし適用されないようであれば一回ターミナル/VSCodeを再起動してください。
Kubernetes - Service と Ingress

# Service

## ClusterIP

Cluster 内の Pod 同士が、内部 DNS で名前解決して通信するプライベート IP アドレス。

![ClusterIP.drawio (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/e239bac9-d925-7e46-a340-678b638c1d6d.png)

## NorePort

Node の IP アドレスに、公開ポート番号を公開して、Cluster 外部からのアクセスを受け付ける。
Service は、kube-proxy と連携して、各 Node にポートを開き、Node 横断で Pod にリクエストを送信。

![NodePort.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/49038a52-9967-a8ab-2011-1e07a51f6003.png)


## LoadBalancer

Cluster 外部の LoadBalancer と連携して外部からのアクセスを受け付ける。各クラウドプロバイダーで対応。

![LoadBalancer.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/4c1c345a-8555-64fe-f791-922d1c3d28db.png)


# Ingress

Ingress は外部からの HTTP(S) トラフィックを内部 Service にルーティングし、L7 のロードバランシングを提供。

![Ingressdrawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/16b0dc47-2aef-3fff-8db1-8d3e79412800.png)
QRadar 初期化インストール

### 目的
- QRadarが部分的に機能不全に陥った場合に、初期インストールバージョンに戻す
- IOSファイルが無く、元QRadarにバージョンに戻す場合
ほぼ通常インストールとかわらないためインストールに２時間ほどかかる

### 手順
1. QRadarを再起動します。途中でFactory re-installを選びEnterキーを押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307206/f7f30ff7-1a36-32d1-b280-157e5c877532.png)

2. flattenと入力してEnterキーを押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307206/9aeb9af1-8b4c-0226-3d21-2b57ca4ca9d8.png)

3. rootを入力してEnterキーを押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307206/46b75468-6ce8-ea46-183c-5ffd61811fc6.png)
4. ライセンス許諾画面に切り替わるので、スペースキーを押してスクリールする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307206/55e70aa7-34cf-aa84-b069-ad433923258e.png)
5. yesと入力してEnterキーを押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307206/68a8cd1c-a02f-c8b6-4766-e95509d68b60.png)

6. Appliance Installになっていることを確認してNext
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307206/3105b713-38af-d1a4-7b8e-a30547836bed.png)

7. All-IN-ONE Consoleになっていることを確認してNext
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307206/6d5ed29f-a682-7283-2732-e868260e35ff.png)
8. normalになっていることを確認してNext
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307206/a6d28697-e6a1-d2a5-e12e-6b9bbfabcb6c.png)
9. 時間を確認してNext
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307206/8f377510-fb5e-88d9-a233-a1ae65f01bc3.png)
10. Asiaを選択してNext
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307206/0ed67ed9-4cd9-b0b8-2fee-93f62198dc50.png)
11. Tokyoを選択してNext
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307206/8c71d23c-a5a9-cb7f-dca3-28f6886e86ea.png)
12. ipv4が選択されていることを確認してNext
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307206/d7c6f98c-c942-784a-1328-10d1a7a0a468.png)
13. 管理コンソールとして利用するNICを選択してNext
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307206/ea3e491b-cd3d-2809-a3f1-c376c1ef63c0.png)
14. Hostname/IP address等を入力してNext
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307206/c013ea95-3cd6-83de-a35f-1decaa14bdc0.png)
15. validating network settings...という画面が出て数分待つ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307206/3833011e-def2-522e-8ac4-2f2fd8db6764.png)
16. linuxでログインするパスワードを入力してFinish
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307206/051e0ff0-84bb-840d-a9a4-39d27fdfb86c.png)
17. WebUIで利用するAdmin用のパスワード入力してNext
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307206/8331eaef-9f75-2360-039c-b585699d3da2.png)
18. Installing QRadar changes...という画面が表示されてここから時間がかかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307206/47fa5554-e5b6-c176-274f-d0fa17f2a98f.png)
19. 終わったら14番で指定したIPアドレスをhttpsを使いブラウザでアクセスするとWebUIが表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307206/38007422-3319-271c-469c-c5077585d75a.png)
作業ログを残そう

# はじめに
今年のカレンダーはとある会社のとあるチームで活動した1年間を振り返っていきます

2022年12月までチームメンバーで新技術を用いてシステム開発をしていましたが、
年内でチームメンバーが転職、年明けから他メンバーは既存案件を対応ということで、しばらく一人で開発を行うことになりました。

# 作業ログを残そう

一人で開発をするとなると技術的負債ができやすいので、作業ログを残すことにしました。
ログを残すことで、
- 他の人が似たような作業をする際に役立つ
- コードレビューをもらう際の補助資料として役立つ
- 自分と対話できる
といったメリットがあると感じました。

デメリットは手間がかかるというところでしょうか。丁寧にログを残そうとするとその分時間がかかってしまうことには注意が必要ですね。「○○で詰まっていたが、△△で解決できた」といったログは残すようにしています。

最後に実際に残していた作業ログをお見せします。(大したことは書いていませんが)
※あくまでログなので正しい情報とは限りません

```
# やりたいこと
・docker環境のためコンテナ起動時は開発用DBになっているので、テスト実行時はテスト用のDBに切り替えたい

# どうすればよさそうか
・DBをテスト用と開発用に分けるために環境変数を利用

# やったこと
・テスト用のDBを用意する。sql実行はgorm構造体のexecメソッドで可能
https://gorm.io/ja_JP/docs/sql_builder.html

この構造体は開発用DBのgorm構造体でよいのか
一旦以下の方法でテスト用DBを用意してみる
①開発用DBのgorm構造体を取得
②テスト用DBを作成
③テスト用DBのgorm構造体を取得
```

# おわりに
当時は社内で実績がない技術を扱っていたため、周りに相談しづらい環境でした。
そのため、作業ログを元に考え方としては合っていそうかという観点で相談をしていました。
javaScript 分割代入　デフォルト値　三項演算子

# 分割代入
### オブジェクトの場合
```js
const myProfile = {
  name: "tami",
  age: "20"
  };
  
  const hello =`私の名前は${myProfile.name}です。年齢は${myProfile.age}歳です。`;
                
  console.log(hello);
```
```
私の名前はtamiです。年齢は20歳です。
```
これと同じものを分割代入で出力しようとすると
```js
const myProfile = {
  name: "tami",
  age: "20"
  };
//波括弧の中にキー名を入れる、イコールの右側はどこからとってくるか
const {name,age} = myProfile;

const hello =`私の名前は${name}です。年齢は${age}歳です。`;
                
console.log(hello);
```
```
私の名前はtamiです。年齢は20歳です。
```

### 配列の場合
```js
const myProfile = ["tami",20];
  
  const hello =`私の名前は${myProfile[0]}です。年齢は${myProfile[1]}歳です。`;
                
  console.log(hello);
```
```
私の名前はtamiです。年齢は20歳です。
```
これと同じものを分割代入で出力しようとすると
```js
const myProfile = ["tami",20];
//配列の場合順番に注意する、設定する変数名は何でもよい
const [name,age] = myProfile;

const hello =`私の名前は${name}です。年齢は${age}歳です。`;
                
console.log(hello);
```
```
私の名前はtamiです。年齢は20歳です。
```
# デフォルト値
関数を実行したとき、引数に値をとらない場合Undifinedになるため
それを解消するためにデフォルト値を設定することができる
```js
//例えば以下のような関数があったとする
const hello = (name) => cosole.log(`こんにちは${name}さん！`);
//このとき引数に何も入れず関数helloを実行するとUndefindeになる
hello();
```
```console
Undefined
```
```js
//デフォルト値を設定するには引数に＝でつないでデフォルト値を記述する
const hello= (name = "ゲスト") => console.log(`こんにちは${name}さん！`);
hello();
```
```console
こんにちはゲストさん！
```
# 三項演算子
if,elseを一行で書けるようなそんなイメージ
```js
let num = 5 ;
const result = num > 0 ? "OK！" : "自然数にしてね！";
console.log(result);
```
```console
OK!
```
半角スペースとバーティカルライン区切りで 10 個出力 (paizaランク D 相当)

実はPythonも今勉強中で、Paizaもやってみている。ちなみにDランクはパスした。
今はCランクに上がるための問題集をこなしている。
phpもやるけど並行してこちらも。

https://paiza.jp/works/mondai/stdout_primer/stdout_primer__specific_split_step5

・10 個の数値が改行区切りで与えられる
・これらの数値を半角スペース 2 つとバーティカルライン | 区切りで出力
・ただし、末尾には改行を出力

回答のポイントとして
・配列に入れるか入れないかで難度が変わる
・私は配列に入れてしまったのでちょっと難易度が上がってしまった
・joinは文字列にしか使えないので、配列を文字列化しないといけない
・リストの各要素をint型からstr型へ変換するときには`map()`を使う。
　第一引数にはstr関数、第2引数はイテラブル、この場合はarrを指定
そんな私の回答がこれ。

```
arr = []
for i in range(10):
    num =int(input())
    arr.append(num)
print(" | ".join(map(str,arr)))

```
ところが、配列に入れなきゃすごく簡単にできた
`print()`をうまく使えてない証拠。。。
`join()`や`split()`と同じくうまく使わんとな

```
for i in range(10):
    if i !=9:
        print(input(),end=" | ")
    else:
        print(input())
```
AssumeRoleについて調べてみた

## 動機づけ
AWS認定試験の学習をしている際にAssumeRoleについての問題で行き詰まり、なかなか理解が難しく、それについて調べていくうちに記事にしようと思いました。
## AssumeRoleとは
ここで、簡単にAssumeRoleとはなんぞやというお話をします。
まずは画像を見るとわかりやすいと思います。
![スクリーンショット 2023-11-09 15.55.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1961802/f4866762-c8fe-781d-fec2-1876cc0f46be.png)

まずはIAMユーザーがSTS（一時的な認証情報を発行してくれるサービス）に対してIAMロール（ここではS3バケット内のオブジェクトを読み取るための権限）が欲しいとリクエストを送り、認証情報を返してもらいます。
画像でいう帽子のようなものがIAMロールです。
この少年は帽子を被ることによってS3を読み取ることができる力を手に入れたということになります。
※実際には、IAMロールと同じ力を一時的に得るといった形になります。
これらの説明から、AssumeRoleとは、IAMロールを引き受けるためのアクションを表します。
## AssumeRoleを使ってどんなことができるのか
こちらもまず画像を先に貼っておきます。
![スクリーンショット 2023-11-09 16.16.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1961802/920e91ad-8720-a781-6d48-21a55881e013.png)

画像の通り、２つのアカウントA, Bがあります。
前提条件として、アカウントAにはLambda関数を実行するロールを、アカウントBにはS3バケットアクセスロールを作成します。
アカウントBにおけるIAMユーザーがアカウントAのlambda実行ロールを代行（AssumeRole）し、lambda関数を実行します。
そしてアカウントBのS3バケットアクセスロールをアカウントAが代行（AssumeRole）し、lambda関数がS3バケットにアクセスできるようになる。
このようなことが実現可能になります。
【補足】
こちらではアカウントBにおけるIAMユーザーがlambda関数を実行していますが、もちろんAssumeRoleを使わずアカウントAにおけるIAMユーザーがlambda関数を実行することも可能です。
## 最後に
最近AWSにおける学習を進めており、一つ一つのサービスを実際に触ってみたり、組み合わせてみたり、点と点が繋がる面白さを味わっています。
認定試験ではAWS CLF, SAAを取得しました。
SAA取得後、[CloudTech](https://kws-cloud-tech.com/) というサブスク型のAWSにおけるオンラインスクールに出会い、気軽に入会してみました。認定試験における画像解説がとてもわかりやすく、ハンズオンも豊富にあり、より一層AWS学習が楽しくなっていきそうです！
気になる方は是非入会してみてください！
### 参考記事
- https://dev.classmethod.jp/articles/iam-role-passrole-assumerole/
- https://zenn.dev/fdnsy/articles/e98c43d9c3f611
Splunkのコンポーネント（基本機能）まとめ

Splunkの代表的な機能を４つを紹介していきます。

### ①インデクサー：Indexer
テキストデータであれば、取り込むことが可能。
検索ができるように、保存(インデックスへの格納)、加工(インデックス化)しておく。
リソースを多用するため、I/OとCPUを十分に割り当てる必要があります。

__・I/O(Input/Output)__：情報入力(Input)と出力(Output)の処理の総称。高頻度でデータ入出力が行われると、ハードウェアやネットワークにI/O処理の負荷が発生するため注意。

### ②サーチヘッド：Search Head
インデクサーに格納されたデータを検索・表示する機能です。
スケジュールで動作するアラート、レポート等の機能もサーチヘッドが提供。

### ③フォワーダ：Forwarder
対象の分析データを収集し、Splunkサーバへ転送する機能を持ったエージェントのこと。
Splunkのインスタンス間でデータ転送を行うものです。
インデクサーやほかのフォワーダー、サードパーティシステムが転送先となります。
ほとんどのフォワーダーは少ないリソースで利用できるため、データを生成するマシン上に無理なくインストール可能。

__・エージェント__：代理人。ユーザーの代理としてコンピュータ処理を行う機能。ソフトウェアやシステム
__・インスタンス__：Splunkを単独で実行するサーバのこと。

主に、マシンから収集したデータをそのままインデクサーに転送するユニバーサルフォアーダと、
条件を絞ったデータのみを Indexer に転送するヘビーフォアーダを利用。
▼フォワーダに種類の詳細は以下記事にあり

https://qiita.com/mizushino/items/75e98cfb01ac457ebf22

### ④ディプロイメントサーバ：Deployment Server
各フォワーダにコンフィグを配信して一括設定できる機能。
導入している機器に直接ログインすることなく設定の変更が可能。
規模が大きい構成等で、フォワーダの数が大きいほど重宝される。

### ●おまけ
環境構成によって、インデクサーやフォワーダの数は変動していきます。
機能は1つのサーバに1個しか使用できないということはなく、当然複数の併用も可能です。

__小規模例：__
インデクサーとサーチヘッドを併用して、1つのサーバ上で機能させる。
![小規模_基本構成_Splunk.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3501557/5dccf8a4-5346-8bec-d953-0c8bc82fb17d.jpeg)


__大規模例；__
上位にサーチヘッドで複数のインデクサーからサーチ結果を検索します。
ディプロイメントサーバも併用してフォワーダの一括管理。
次層にはインデクサーを複数配置して、負荷分散を行う。
以降の各マシンにはフォワーダをインストールします。
![Splunk_大規模フォワーダ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3501557/c8cdd95f-968e-b938-0d7d-54e89259ffe9.jpeg)
Oracle Application Express (APEX) の基本情報

# 1. はじめに
APEXは、以前は「Oracle HTML DB」と呼ばれていたそうです。
以前に、「[【Oracle APEX】(初心者向け) チュートリアルから派生して、各種基本機能を試してみた](https://qiita.com/shi6maSencho/items/05336503bda6e82c02cd)」にて、APEXの基本操作についてご紹介しました。

今回は実際の利用するにあたっての情報をまとめようと思います

# 2. APEXのインストールマニュアルとダウンロード先
| Oracle Database | APEX ver | マニュアル | ダウンロード先 |
| :-: | :-: | :-: | :-: |
| 19c以上 | 23.1 | [こちら](https://docs.oracle.com/cd/F86785_01/installandupgrade.html) | [こちら](https://apex.oracle.com/ja/learn/getting-started/) |
| 12.1.0.2以上 | 22.2 | [こちら](https://docs.oracle.com/cd/F79039_01/installandupgrade.html) | [こちら](https://www.oracle.com/jp/tools/downloads/apex-downloads/) |
| 11.2.0.4以上 | 20.2 | [こちら](https://docs.oracle.com/cd/F39413_01/installandupgrade.html) | [こちら](https://www.oracle.com/tools/downloads/apex-202-downloads.html) |

# 3. OnPでも利用可能か
[こちら](https://apex.oracle.com/en/platform/powered-by-oracle/) のサイトに以下と記載
>Oracle Databaseが実行される場所であればどこでも実行可能
Oracle APEXは、オンプレミス、Oracle Cloud、その他の場所を問わず、Oracle Databaseが実行される場所であればどこでも実行できます。

# 4. APEXのロードマップ
[Oracle Technology Products -Oracle Lifetime Support Policy-](https://www.oracle.com/us/assets/lifetime-support-technology-069183.pdf) にて、
「Oracle Application Express」で検索いただくと、**premire supportの終了時期を確認可能**

# さいごに
必要情報あれば、少しずつ更新していこうと思います。
GPT-4Vで画像を解析する



## はじめに
GPT-4Vは、テキストだけでなく画像も理解できる革新的なAIモデルです。

ここでは、初心者でも理解しやすいように、GPT-4Vを使って画像解析を行う方法を紹介します。

## 必要なもの
- **OpenAIのAPIキー**: GPT-4を使用するためには、OpenAIのAPIキーが必要です。
- **Python**: このコードはPythonで書かれています。

## コードの説明
GPT-4Vを使って画像に関する質問に答えるためのPythonコードは以下の通りです。

```python
from openai import OpenAI

client = OpenAI()

response = client.chat.completions.create(
    model="gpt-4-vision-preview",
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "What’s in this image?"},
                {
                    "type": "image_url",
                    "image_url": {
                        "url": "画像のURL",
                    },
                },
            ],
        }
    ],
    max_tokens=300,
)

print(response.choices[0])
```

### 処理詳細
1. **ライブラリのインポート**: `from openai import OpenAI`でOpenAIライブラリをインポートします。
2. **クライアントの設定**: `client = OpenAI()`でOpenAIのクライアントを設定します。
3. **リクエストの作成**: `chat.completions.create`メソッドを使って、質問と画像URLを含むリクエストを作成します。
4. **画像URLの指定**: `"url": "画像のURL"`の部分に、解析したい画像のURLを指定します。
5. **応答の出力**: `print(response.choices[0])`でモデルからの応答を出力します。
単回帰分析におけるL1正則化、L2正則化について

# 1.はじめに
単回帰分析におけるL1正則化（Lasso正則化）とL2正則化（Ridge正則化）に関する記事を以下に示します。この記事では、それぞれの正則化手法の概要、用途、メリット、デメリットなどを説明します。
# 2. L1正則化とL2正則化
## 単回帰分析とは
単回帰分析は、1つの説明変数と1つの目的変数の関係を調査する統計的手法です。目的は、説明変数と目的変数の間の関係をモデル化し、説明変数から目的変数を予測するモデルを構築することです。

## L1正則化（Lasso正則化）
L1正則化（Lasso正則化）は、単回帰分析において、モデルの係数を0にする傾向がある正則化手法です。これはスパース性を持つモデルを促進し、不要な説明変数を選別するのに役立ちます。
$$ E(w) = \frac{1}{N} \left(\sum_{i=1}^{N} {(y_i - (\mathbf{x}_i ^T\mathbf{w}))^2}\right) + λ (\sum^{D} {|w_j|}) $$

ここで、

**w** はパラメータのベクトル
$N$ はデータポイントの数
$y_i$ は i 番目の観測値
$\mathbf{x}_i$ は i 番目の説明変数のベクトル
$p$ は説明変数の数
$λ$ はL1正則化の強度パラメータ
$D$ は**w**の要素数
L1正則化項は $|w_j|$ で表され、各係数 $w_j$ の絶対値を足し合わせます。この項によって、係数が0に収束し、スパースなモデルが生成されます。

### 用途
多くの説明変数がある場合、L1正則化を使用して特徴選択を行い、モデルを単純化することができます。ノイズの影響を減らすために使われることがあります。
### メリット
スパースなモデルを生成し、不要な説明変数を排除できます。不要な説明変数を削除することで人間に分かりやすい特徴量を見つけることや、計算量の軽減を行うことができます。また、過学習のリスクを減少させることができます。
### デメリット
ハイパーパラメータ（正則化の強度）を調整する必要があります。小さすぎると正則化が行われず、大きすぎると機械学習の精度が落ちます。
## L2正則化（Ridge正則化）
L2正則化（Ridge正則化）は、単回帰分析において、モデルの係数を0にする傾向が少なく、係数を均等に縮小します。これは共線性（説明変数間の相関）の影響を軽減するのに役立ちます。
$$ E(w) = \frac{1}{N} \left(\sum_{i=1}^{N} {(y_i - (\mathbf{x}_i ^T\mathbf{w}))^2}\right) + λ (\sum^{D} {|w_j|^2}) $$
### 用途
説明変数間に高い相関がある場合、L2正則化を使用して共線性を軽減できます。モデルの過学習を制御するために使われることがあります。
### メリット
共線性の影響を軽減し、安定したモデルを生成します。
ハイパーパラメータの調整が比較的簡単です。
### デメリット
スパース性を持つモデルを生成しづらい場合があります。
# 3.まとめ
L1正則化（Lasso正則化）とL2正則化（Ridge正則化）は、単回帰分析において過学習や共線性の問題に対処するための強力な手法です。正則化を適切に選択し、モデルの性能を向上させるために活用しましょう。
JavaScriptで関数の呼び出し元を知る方法

# JavaScriptで関数の呼び出し元を知る方法

## はじめに
プログラミングの世界では、「どの関数からこの関数が呼ばれたのか？」を知りたい場面がよくあります。特に、JavaScriptで開発をしているとき、この情報がデバッグに非常に役立ちます。


今回は、JavaScriptで現在の関数がどの関数から呼ばれたかを表示する方法を、初心者の方にもわかりやすく説明します。

## 手順

### 1. `Error`オブジェクトを作る
JavaScriptには`Error`というオブジェクトがあり、これを使ってエラー情報を得ることができます。ここでは、エラーを起こすのではなく、その機能を利用します。

```javascript
const error = new Error();
```

### 2. スタックトレースを取得する
スタックトレースとは、プログラムの呼び出し履歴のことです。この履歴から、どの関数がどの順番で実行されたかを知ることができます。

```javascript
const stack = error.stack || '';
```

### 3. 呼び出し元の関数を見つける
スタックトレースの中から、現在の関数の次に来る行が、呼び出し元の関数になります。

```javascript
const stackLines = stack.split('\n');
const callerIndex = stackLines.findIndex(line => line.includes('getCaller')) + 2;
```

### 4. 関数名を表示する
最後に、見つけた呼び出し元の関数名を`console.log`を使って表示します。

```javascript
if (stackLines[callerIndex]) {
  console.log(stackLines[callerIndex].trim());
}
```

## 実践例
上記の手順を組み合わせて、実際の関数で使ってみましょう。

```javascript
function getCaller() {
  const error = new Error();
  const stack = error.stack || '';
  const stackLines = stack.split('\n');
  const callerIndex = stackLines.findIndex(line => line.includes('getCaller')) + 2;
  if (stackLines[callerIndex]) {
    return stackLines[callerIndex].trim();
  }
  return 'Unknown';
}

function yourFunction() {
  console.log('Called by:', getCaller());
  // ここに他のロジックを書く
}

function anotherFunction() {
  yourFunction();
}

anotherFunction();
```

このコードは、`anotherFunction`から`yourFunction`が呼ばれ、その結果として呼び出し元がコンソールに表示されます。

## 注意点
- この方法は、ブラウザやJavaScriptの実行環境によって結果が異なることがあります。
- スタックトレースの形式はブラウザによって異なりますので、異なるブラウザでの動作確認が必要です。
公開鍵暗号を本当の鍵に例えてみたので聞いて欲しい

## プロのWabエンジニアとしてのプライドを持つ
普段Webアプリケーションを開発していますが、近年はAWSなどのサーバーレス開発サービスやフレームワークの普及により、Webサーバーの構造を意識しなくてよく、アプリケーション開発に専念できるという恩恵を受けています。

しかしその影響もあってか、サーバーで何が行われているのか、サーバーとクライアントがどのように安全な通信を行なっているのかを知らない、というか興味すらないという状態でした。
これではまるでプロの料理人が
「__中身よくわからんけど美味しいから"味の素"の調味料使っとこ__」
と言って料理をしているようなものです。（断言）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2388259/2a00a485-e9ed-a3b6-bc22-3f3f3ef5ff34.png" width="30%">

たしかに便利な調味料を使えば簡単に美味しい料理は作れますが、細かい味の調整や、お客さん一人一人の要望（好みとかアレルギーとか）に応える料理ができないかもしれません。
もちろんレストランの種類にもよりますが、こんなのプロの仕事じゃない！。せめてその調味料の成分くらいは知っておいた方ができることは増えるはずです。
ってことで自分はWebサーバーについても勉強していこうというお話でした。

### 追記

現在SSL/TLSでは公開鍵暗号は使われていないようでしたので、公開鍵暗号の一般的な概念を理解するための記事としてご参照ください。

## 公開鍵暗号の流れ

### その前に「共通鍵暗号方式」と「公開鍵暗号方式」
- 共通鍵暗号方式
    - 送信者と受信者が同じ鍵を持っている
    - 暗号化と複合の両方に使える
- 公開鍵暗号方式
    - 盗聴防止用途の場合、受信者が秘密鍵と公開鍵を持っている
    - 送信者に公開鍵で暗号化させた暗号は、受信者の秘密鍵でしか複合できない

### 例を交えて公開鍵暗号での鍵交換を解説
サーバーとクライアントがSSL通信を行うために公開鍵暗号を用いて鍵交換を行った場合を想定します。
ここではサーバーとクライアントを
__【鯖江（サバエ）さん】__
と、
__鯖江さんの友人【倉本（クラモト）さん】__
に例えて説明します。
なお、詳しい解説部分はこちらの記事を引用しています。
https://college.globalsign.com/ssl-pki-info/ssl-encryptions/

#### 1. 接続要求
~~~
クライアント側からSSL通信のリクエストをサーバ側へ送信。
~~~
鯖江さんと倉本さんは共有の別荘を新しく建てましたが、今は倉本さんが別荘の鍵を2人分持っている状況です。
倉本さんは鯖江さんに鍵を渡したいのですが、鯖江さんが海外にいるため今は直接会うことができません。
鍵を直接郵送するのはリスクがあるので避けたいと考えています。

_倉本さん_
「別荘の鍵渡したいねんけど、どうすればええかな、鍵を裸で送るのは怖いから嫌や」

_鯖江さん_
「ほな俺のキーボックス送るからそれに別荘の鍵入れて送り返してきて。
ちなみにこのキーボックスには __閉める専用の鍵__ と __開ける専用の鍵__ があって、閉める専用の鍵はキーボックスと一緒に送るわ」

_倉本さん_
「変なキーボックスやな、了解」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2388259/04ddf016-f0c6-909f-8373-5879aafadd51.png)


#### 2. SSLサーバ証明書と公開鍵をクライアント側へ送付
~~~
サーバ側から、公開鍵付きのSSLサーバ証明書がクライアント側に送付。
クライアント側のブラウザに搭載されているルート証明書で署名を確認し、SSLサーバ証明書を検証。
~~~

鯖江さんは倉本さんにキーボックスを郵送で送りました。
倉本さんは配送元が鯖江さんであることを確認して、まだ鍵のかかっていないキーボックスと、そのキーボックスを閉めるための鍵をゲットしました。

#### 3. 共通鍵(セッションキー）を暗号化しサーバ側へ送付（鍵交換成立！）
~~~
クライアント側で生成された暗号用の「共通鍵(セッションキー）」を、サーバ側から送られてきた公開鍵を用いて暗号化し、サーバ側へ送信。
サーバ側に送信された共通鍵は、サーバ側で保持している秘密鍵で復号され、共通鍵が取り出される。
鍵交換が成立。
~~~

倉本さんは言われた通り、別荘の鍵をキーボックスに入れ、
一緒に送られてきた「閉める専用の鍵」を使ってキーボックスを閉めました。倉本さんはもう開けることはできません。
そしてそのキーボックスを鯖江さんに送り返しました。

このキーボックスは鯖江さんが個人で厳重に管理している「開ける専用の鍵」でしか開けられないので、途中で誰かにキーボックスを開けられて、中の別荘の鍵を取られるなどの心配はありません。

#### 4. SSL暗号化通信開始
~~~
個人情報などの機密性の高いデータを、クライアント側で保持している共通鍵で暗号化しサーバ側へ送信。
サーバ側は、受け取った暗号データをサーバ側で保持している共通鍵で復号してデータを取得する。
~~~

無事鯖江さんのもとにキーボックスが届き、鯖江さんは自身のみが持つ「開ける専用の鍵」でキーボックスを開け、別荘の鍵を取り出すことができました。
これで二人とも別荘に出入りすることができるようになりました。

_~めでたしめでたし~_

#### 「別荘の鍵」「閉める専用の鍵」「開ける専用の鍵」について
上記の例では鍵が３種類出てきました。
- キーボックスの閉める専用の鍵
    - サーバーの公開鍵にあたる
    公開鍵はSSLサーバ証明書に含まれており、クライアントが受け取るもの
- キーボックスの開ける専用の鍵
    - サーバーの秘密鍵にあたる
    サーバーだけが持っている
- 別荘の鍵
    - データ送受信のための共通鍵にあたる
    共通鍵がサーバーに渡った後は、これを使ってデータを暗号化・復号する

## まとめ
公開鍵暗号では、公開鍵と秘密鍵の片方が暗号専用、もう片方が復号専用となります。
なお、今日のSSL/TLSではDH鍵共有などを用いた共通鍵の共有方法が一般的です。
GPTsを作って公開するのが呆れるほど簡単でウケた

２時間ぐらい経つけど、３つ作りました。簡単すぎて呆れます。似たようなシステムを作っている人が気の毒なぐらい・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103139/3cc06db9-7f2a-0906-e259-128461ce1b9b.png)

以下、それぞれのGPTsのリンクです（ProかEnterprise持っていないと見えないのかな・・・）

- [プログラミング的思考ガイドさん](https://chat.openai.com/g/g-8ZfirfnYv-puroguramingude-si-kao-gaidosan)
- [シアトル釣りガイドさん](https://chat.openai.com/g/g-kT0QP7uGj-siatorudiao-rigaidosan)
- [Seattle Salmon Fisher](https://chat.openai.com/g/g-yueYdFM99-seattle-salmon-fisher)

設定の手順を書こうかと思いましたが、ほんと単純でわざわざ書かなくてもすぐに分かるぐらい簡単なので省略します。

コツとしてはタイトル等すべて日本語に出来るってことと、Knowledge というセクションでネタのファイルをアップロードできる、という点さえ押さえておけばすぐにできます。

# １個目のGPTs：ナレッジ無し
順番は上のリストと逆になりますが、まずは実験として、GPTモデルのみでトピックを絞った「Seattle Salmon Fisher」という英語話者向けのもの。この段階では日本語で作れるって知らなかったので。こいつはGPTモデルが学習した内容だけで応答します。

これは既存の Custom Instructionsと機能的には同じと考えていいと思います。これだけでも「内容を絞りこんだモデル」という意味で価値があると思いますが、プラスアルファがあるわけではない点で差別化要因が見当たりませんね。

# ２個目のGPTs：ナレッジとしてテキストファイルをアップロード

ということで２個目は日本語で「シアトル釣りガイドさん」というGPTsを作りました。作成のプロセスは英語で、会話形式で設定を進めていきますが、GPTが英語で質問してもかたくなに日本語で言えば、ちゃんと設定してくれます。

2個目はプラスアルファとして「自分のナレッジ」を反映させたいので「はてなブログ」にこの5年ぐらいの間に投稿した[釣り関連の記事](https://watanabe-tsuyoshi.hatenablog.com/archive/category/%E9%87%A3%E3%82%8A)をアップロードしてみました。手順は：

1. はてなブログからテキストとしてブログ記事をすべてエクスポートする（この際、釣り関連以外のブログ記事もイクスポートされました）
1. GPTsの設定ページの「Knowledge」セクションでテキストファイルをアップロード

これだけで、例えば「シアトルで初心者向けの釣りは？」と聞いたら、[２０１７年に書いたこの「カレイ釣り」](https://watanabe-tsuyoshi.hatenablog.com/entry/2018/01/02/153054)の内容が出てきました。

## PDFは重い？それともデータサイズが問題？
ところで、ワシントン州の釣りレギュレーションPDF（30KB程度）もアップロードしてみましたが、これはどうやら処理に負荷がかなりかかるようで、ごく簡単な質問も失敗するようになったのでナレッジセクションからいったん削除しました。削除したら応答時間は改善しました。PDFという形式が問題だったのかファイルサイズが問題だったのか、その両方か分かりませんが注意が必要なようです。

# ３個目のGPTs：ナレッジとしてWORDファイルをアップロード

３つめは以前Amazonにキンドル本として出した[シアトルで実践する「プログラミング的思考」という本](https://www.amazon.co.jp/%E3%82%B7%E3%82%A2%E3%83%88%E3%83%AB%E3%81%A7%E5%AE%9F%E8%B7%B5%E3%81%99%E3%82%8B%E3%80%8C%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E7%9A%84%E6%80%9D%E8%80%83%E3%80%8D-%E3%82%B7%E3%82%A2%E3%83%88%E3%83%AB%E3%81%AE%E7%8F%BE%E5%BD%B9%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%8C%E5%AE%9F%E8%B7%B5%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E6%80%9D%E8%80%83%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3-%E6%B8%A1%E8%BE%BA%E6%AF%85-ebook/dp/B09LM24XBK)の元データがWORD形式であるので、それをアップロードしてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103139/da18474e-6cba-b059-1d28-e5ec91150164.png)

さて、この本の内容をナレッジに設定したGPTsはどうなったかというと・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103139/67f71d77-75db-0d96-ea84-f2c1166c5c76.png)

かなり自分が本に書いた内容に沿った応答が出ました。

これはちょっと感動ですね。

# まとめ

GPTsの設定が簡単で、あまりにあっという間に自分のコンテンツを反映した会話型AIモデルが出来て呆れてました。
Laravel - Dockerfileでnode.jsを導入時setup_.xxが使用できない時

DockerでPHP(Laravel)の環境構築をしていた際、node.jsの導入において
以前記述していたスクリプトが使用できずエラーになりました。

結論、Dockerfileの内容を以下のサイトに記載されている内容に変更することで解決しました。
https://github.com/nodesource/distributions/blob/master/README.md

## 以前のDockerfile内容（node.jsの部分だけ抜粋）
```dockerfile
FROM php:8.2.0-apache
<・・・中略・・・>
RUN curl -sL https://deb.nodesource.com/setup_18.x | bash -
RUN apt-get install -y nodejs
```

### エラー内容
```terminal
 => ERROR [<アプリ名> stage-0 9/9] RUN apt-get install -y nodejs                                                                                                                              1.1s
------
 > [<アプリ名> stage-0 9/9] RUN apt-get install -y nodejs:
#0 0.177 Reading package lists...
#0 0.450 Building dependency tree...
#0 0.532 Reading state information...
#0 0.618 The following NEW packages will be installed:
#0 0.618   nodejs
#0 1.017 0 upgraded, 1 newly installed, 0 to remove and 42 not upgraded.
#0 1.017 Need to get 28.1 MB of archives.
#0 1.017 After this operation, 188 MB of additional disk space will be used.
#0 1.017 Err:1 https://deb.nodesource.com/node_18.x bullseye/main arm64 nodejs arm64 18.17.1-deb-1nodesource1
#0 1.017   404  Not Found [IP: 172.67.10.205 443]
#0 1.033 E: Failed to fetch https://deb.nodesource.com/node_18.x/pool/main/n/nodejs/nodejs_18.17.1-deb-1nodesource1_arm64.deb  404  Not Found [IP: 172.67.10.205 443]
#0 1.033 E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?
```

## 原因
GitHub上の「nodesource README.md」を確認したところ、New Updateということでインストール方法の変更がありました。
その中でインストールスクリプトとして存在した「setup_XX.x」はもうサポートがされないと記載があり、そのため以前使用していたスクリプトは使用不可、404(ページがなかった)となっていたようです。

## 今回実施した解決策
そのため、以下のサイトを参考にDockerfileを修正しました（node.jsの部分だけ抜粋）
https://github.com/nodesource/distributions/blob/master/README.md

```Dockerfile
FROM php:8.2.0-apache
<・・・中略・・・>
RUN apt-get update \
  && apt-get install -y ca-certificates curl gnupg \
  && mkdir -p /etc/apt/keyrings \
  && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
  && NODE_MAJOR=18 \
  && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list \
  && apt-get update && apt-get install nodejs -y
```

この記述に変更したところ、きちんとnode.jsが導入されました。

## 後日もう一度「setup_xx」を試した結果→なぜか上手く導入された
今回エラーが発生した際に上記の方法で対応したのですが、後日念のため以前のDockerfileで導入したところ、エラーが発生しませんでした。
まだ理由は分かっていないのですが、もし同様のエラーが出た際、この内容を参考に修正をしてみてください。

構築時にエラーが出ると困るので、今後は修正後の内容で構築しようと考えています。
MagicPodの定期実行をダッシュボードで可視化してみた

# はじめに
こんにちは。QAエンジニアをしている田井です。

前回の[MagicPodを使って本番環境で定期実行してみた](https://qiita.com/kotatoshi/items/a51bb3f40e1c96b1d609)に続き、MagicPodの話です。
今回はMagicPodで定期実行している回帰テストの結果をダッシュボードで見れるようにした話をします！

# ダッシュボードを作ろうとした理由

元々QAチーム内では結果を振り返りで確認したり、GASでスプレッドシートに吐き出すような機能はあったのですが、
エンジニアやPOなどとは細かく共有できていませんでした。
QAイベントなどでもデータは公表していましたが、社内での共有はまだ足りてないという課題感がありました。

そこで、[こちら](https://magicpod.com/customer-stories/locoguide/)の記事で知った[MagicPod-Analyzer](https://github.com/takeyaqa/magicpod-analyzer/blob/main/README.ja.md)を使うことにしました。採用した理由としては、自分自身がコーディングなどの知識が乏しく自前では難しいことと、使い方の細かく説明があることでした。

# MagicPod-Analyzer&BigQuery&LookerStudio
![スクリーンショット 2023-11-02 9.39.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151058/64a42d8d-61b8-80e0-90ad-a51a978ba607.png)

上の画像のようにLookerStudioを使い、ダッシュボードを作りました。

データの取得と格納にはAutomator、Automatorを自動で実行するにはMACのカレンダー機能を使いました。もっとスマートなやり方はあるのでしょうが、自分が管理できる範囲でということが大前提のためAutomator&カレンダー機能にしました。

## 処理の流れ

処理的には以下のようなことをしています(AndroidとiOSで別々で実行しています)。
1. MagicPod-Analyzerで最新データをダウンロード
1. リネーム＆オリジナルを保存()
1. jqコマンドで整形
1. BigQueryへデータをロード
1. リネームしたファイルを削除

### データの取得
データの取得はMagicPod-Analyzerのreadme通りに準備を進めていきました。
まずはターミナルで実行してみて、ファイルが保存されることを確認。
そのコマンドをAutomatorに設定しました。

また、Slackで通知するようもしたので、通知内のリンクからPDFファイルを見れるようになりました。

### データの格納
データの格納も定期的に行うため、Automatorで設定しました。
定期実行は平日の朝走るので、昼頃にデータの取得をしたら、格納を行うように設定しました。

これにより会社全体に共有できたのですが、、BigQueryは無料プランで使っていたため、DBが削除されてしまいました(認識してなかったんです)。。
課金すればすぐに解決するのですが、ダッシュボードだけのためにコストをかけるのことはしたくなかったので、別の方法を考えることにしました。

# GAS&Gooogleサイト
![スクリーンショット 2023-11-01 20.49.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151058/cc90c5a2-efad-1dca-84c0-99f05588412b.png)

その時に思い付いたのが、QAチームで作成したGASでも定期実行などのデータを取得していたということでした(最初から思いつけばよかったんですが。。)。
そこで、スプレッドシートにあるデータを使い、ダッシュボードのようなものを作れるのではと思い、Googleサイトを使い作成を開始しました。
Googleサイトではスプレッドシートを登録して、そこからデータを引っ張ってくる形です。
Googleサイトなので若干見栄えは劣りますが、、必要なデータは表示することができました。
定期実行以外にも回帰テストの結果なども表示していて、振り返りなどで確認したりしています。
公開範囲は社内メンバーのみにしています。

# 最後に
MagicPodでの回帰テストの実行や定期的なテスト実行だけでなく、データを共有できるようになり、社内でのテスト自動化についての認知度などがあがったと考えています。
社内での「MagicPodで何してるんだろう？」という疑問も解決できたと思っています！
何よりもダッシュボードでわかりやすいので、データの分析などにも活用できそうです！
Poetryでインストール時のpythonバージョンに関わるエラー

### 発生したエラー
Poetryでライブラリをインストールしようとすると以下のようなエラーが出ることがあります。
今回はnumpyをインストールしようとしたときのエラーです。

```sh
$ poetry add numpy

...

The current project's supported Python range (>=3.10,<4.0) is not compatible with some of the required packages Python requirement:
  - numpy requires Python <3.13,>=3.9, so it will not be satisfied for Python >=3.13,<4.0

Because numpy (1.26.1) requires Python <3.13,>=3.9
 and no versions of numpy match >1.26.1,<2.0.0, numpy is forbidden.
So, because paddy depends on numpy (^1.26.1), version solving failed.

  • Check your dependencies Python requirement: The Python requirement can be specified via the `python` or `markers` properties
    
    For numpy, a possible solution would be to set the `python` property to ">=3.10,<3.13"

    https://python-poetry.org/docs/dependency-specification/#python-restricted-dependencies,
    https://python-poetry.org/docs/dependency-specification/#using-environment-markers
```

### 解決方法

pyproject.tomlファイルのpythonのバージョンをエラー中の`">=3.10,<3.13"`に従って書き換え、再度ライブラリをインストールするとうまくいきます。

```pyproject.toml
[tool.poetry.dependencies]
python = ">=3.10,<3.13"
```
重回帰分析まとめ

# 重回帰分析について

## 1. 概要

重回帰分析は、複数の説明変数が従属変数に対してどのような影響を持つかを分析する統計的手法です。この分析では、ベクトル **w** を使用して、従属変数を説明変数の線形結合としてモデル化します。ベクトル **w** は回帰係数で、バイアス項 **b** と共に最適な値を見つけるために勾配降下法を使用します。

## 2. 目的関数（損失関数）

重回帰分析の損失関数 E を次のように定義します。
$$
E(\mathbf{w}) = \frac{1}{N} \sum_{i=1}^{N} (y_i - (\mathbf{x}_i ^T \mathbf{w}))^2
$$

ここで、  
- $\mathbf{w}$ は回帰係数とバイアス項を含むベクトル
- $N$ はデータポイントの数
- $y_i$ は i 番目の観測値
- $\mathbf{x}_i$ は i 番目の説明変数のベクトル
- E(**w**) はパラメタベクトル$\mathbf{w}$に関する損失関数

## 3. パラメータの更新式（勾配降下法）
パラメータ **w** を最適化するために、勾配降下法を使用します。損失関数 E(**w**) を最小化する **w** を見つけるため、以下の更新式を使用します。
$$\mathbf{w'} ← \mathbf{w} - α * ∇E(\mathbf{w})$$


ここで、  
- **w** は回帰係数とバイアス項を含むベクトル
- $α$（アルファ）は学習率（更新ステップの大きさ）
- ∇E(**w**) は損失関数 E(**w**) の勾配ベクトル

基本的な考え方は単回帰と同一です。勾配と逆方向にパラメータを更新することで、誤差関数の値を減らす方向に向かいます。損失関数 E(**w**) の勾配ベクトル ∇E(**w**) を計算する必要があります。これは、各回帰係数とバイアス項に対する偏微分を計算し、ベクトルとしてまとめたものです。

勾配は
$$
∇E(\mathbf{w}) = \frac{2}{N} \sum_{i=1}^{N} (\mathbf{x}_i ^T \mathbf{w} - y_i) \mathbf{x}_i$$
これを以上の更新式に代入することで、最急降下法によるパラメータの更新を行うことができます。実際は誤差関数の値が閾値を下回ったときに打ち切ります。

## 4. まとめ
以上で最急降下法を用いて、重回帰分析を行うことができます。また、行列計算を用いて重回帰分析を行う方法もありますが、計算量が非常に多いため変数が多くなると使用が難しくなってきます。
【Minecraft】サブドメインでリバースプロキシしたい！

マインクラフトでバニラサーバーとMODサーバーを立てた際、Nginxのリバースプロキシができるか試した時の話
# あらすじ
・Minecraftサーバーをを同一サーバー上で2つ立てた
・ポート番号をそれぞれ書くのがめんどくさい
・サブドメイン変えるだけで入れるようにしたい！

# 方法１- Nginxのリバースプロキシ
> リバースプロキシとは、クライアントからのリクエストを受け取り、
それをバックエンドのサーバーに中継するプロキシサーバーのこと

通常複数のホームページなどを同一IPでホストするときに使う。
```bash
abc.example.com => localhost:80

def.example.com => localhost:81
```
などサブドメインを判別し、接続先を振り分けてくれる。

マイクラのサーバーにも使えるのでは？
```bash
abc.example.com => localhost:25565

def.example.com => localhost:25566
```

### 結果：接続できなかった
MinecraftのサーバーはTCP通信だがTCPの規格上、HTTP通信のようにサブドメインを検出することができず振り分けができないらしい

# 方法２ - SRVレコードを使う
> SRVレコードは、"Service"レコードの略で、ドメインネームシステム（DNS）で使用される一種のリソースレコードです。サービスが利用するポート番号を指定することができます。

DNSで名前解決する段階でport番号も一緒に送られてくる便利なレコードらしい。

## やってみる
DNSサーバー: Cloudflare

接続したいサーバー
```bash
example.com => IPアドレス:25565
mc.example.com => IPアドレス:25566
```

![スクリーンショット 2023-11-09 15.05.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819887/10212ebb-cce0-bde1-f556-ca8a17e29a57.png)
![スクリーンショット 2023-11-09 15.04.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819887/c9a9a253-bd66-df98-b96c-30ef3e9fa1d1.png)


### 結果：接続できた
あっさりと繋がった。実はネット上の多くの文献にはminecraftサーバーではSRVレコードは使えないと書かれていたため、ダメ元でやってみたのだが全く問題なく繋がった。

Minecraftサーバーのバージョンにもよるのかもしれないが、1.20.1では使用できる
M5StackのUnit EncoderをM5Unifiedと共に使うClass

# はじめに

前回、M5StackのUnit Encoderのファームウェアをアップデートしました。追加された機能が使えて、いつも利用しているM5Unifiedと連携できるクラスがほしかったので作りました。M5Unifiedの書き方に準じつつ、Unit EncoderのExampleのメンバ関数とだいたい同じ感じになるようにしています。

https://qiita.com/8ga3/items/ed60578a1d55e32bfc2b

# ライブラリ共有

GitHubにリポジトリを作りました。`lib/UnitEncoder_Class/UnitEncoder_Class.cpp`が該当します。platformioのプロジェクトの形になってます。

https://github.com/8ga3/UnitEncoder_Class_M5Unified

# 初期化

setup関数でbegin()をコールしてください。PORT.AのI2Cに繋がっているものとして初期化されます。

```cpp:main.cpp
#include <M5Unified.h>
#include <UnitEncoder_Class.hpp>

m5::UnitEncoder_Class UnitEncoder;

void setup()
{
  auto cfg = M5.config();
  M5.begin(cfg);
  UnitEncoder.begin();
}
```

# メンバ関数

## setEncoderMode (V1.1)

```cpp
void setEncoderMode(encoder_mode_t mode);
```

ロータリーエンコーダーのモードを設定します。

**パラメータ**
* *mode* :

| name | 説明 |
|:-----|:-----|
|m5::UnitEncoder_Class::encoder_mode_t::mode_pulse | 時計回りはカウントアップ、反時計回りはカウントダウンします。 |
|m5::UnitEncoder_Class::encoder_mode_t::mode_ab | 絶対角度 |

## getEncoderValue

```cpp
signed short int getEncoderValue();
```

ロータリーエンコーダーの値を取得します。setEncoderMode()の設定によって取得できる値は変わります。

**戻り値**
* ロータリーエンコーダーの値

## setEncoderValue (V1.1)

```cpp
bool setEncoderValue(signed short int value);
```

ロータリーエンコーダーの値を設定します。起動直後は0が設定されています。

**パラメータ**
* *value* : -32768 ~ 32767

**戻り値**
* 成功したかどうか

## getButtonStatus

```cpp
bool getButtonStatus();
```

ボタンが押されているかどうかを取得します。

**戻り値**
* 押下状態

## setLEDColor

```cpp
void setLEDColor(uint8_t index, uint32_t color);
```

LED色を設定します。

**パラメータ**
* *index* : LED番号
  * 0: すべてのLED
  * 1: LED1
  * 2: LED2
  * その他: 未定義
* *color* : 0x00RRGGBBの順のフルカラー指定

## resetCounter (V1.1)

```cpp
bool resetCounter();
```

リセットします。

**戻り値**
* 成功したかどうか

## おわりに

今後も手持ちのM5Stackモジュールを、M5Unified対応にして使っていきたいと思います。少ししか持っていませんけど。