OmniAICreator/Qiita-1.07M huggingface dataset:
Python venv メリットと使い方

## はじめに

今日はPythonのvenv（仮想環境）についてです。venvって何？どうやって使うの？って疑問に答えていきます。


## venvとは
venvは手軽に仮想環境を作成・管理できる、Pythonのライブラリの一つです。Pythonの仮想環境を作成するための軽量な仮想環境の作成を行ってくれます。
また、venvはPythonバージョン3.3以降の標準ライブラリとして提供されており、バージョン3.3以降のPythonをインストール済みの方はvenvを別途インストールすることなく利用可能です。


## venvのメリットって？
続いて、venvのメリットを見ていきましょう。

1. プロジェクトごとに環境を分けられる
例えば、あるプロジェクトではPython 3.8を使っていて、別のプロジェクトではPython 3.9を使いたいなんてことがありますよね。venvを使えば、各プロジェクトごとに異なるPythonのバージョンやパッケージを管理できるので、干渉してしまう...という困り事を解消できます。

2. 依存関係の管理が楽
複数のプロジェクトで同じパッケージを違うバージョンで使うこともよくあります。venvを使えば、それぞれのプロジェクト内に依存関係を隔離して管理できるので、他のプロジェクトに影響を与えずにパッケージをインストールできます。

3. クリーンな開発環境
仮想環境を使うことで、PC本体のPython環境を汚さずに済みます。開発が終わったらその環境ごと削除するだけなので、システム環境がすっきり保てます。


## 使い方
さて、venvの使い方を見ていきましょう。手順はとっても簡単です。


1. 仮想環境の作成
    まずはプロジェクトのディレクトリに移動して、仮想環境を作成します。
    ここでmyenvは仮想環境の名前です。好きな名前を付けてOKです。仮想環境名は、よく`venv`と名付けられることが多いので、こだわりなければ`python3 -m venv venv`でもいいと思います。
    ```
    $ python -m venv myenv
    ```

2. 仮想環境の有効化
仮想環境を有効にするには、以下のコマンドを実行します。
    
    - Windowsの場合:
    ```
    $ myenv\Scripts\activate
    ```
    - MacOS/Linuxの場合:
    ```
    $ source myenv/bin/activate
    ```
    
    これで仮想環境が有効化されます。ターミナルのプロンプトに(myenv)と表示されるはずです。
    参考：[venv --- 仮想環境の作成.仮想環境のしくみ](https://docs.python.org/ja/3/library/venv.html#how-venvs-work)

3. パッケージのインストール
    仮想環境が有効な状態で、必要なパッケージをインストールします。
    ```
    (myenv) $ pip install numpy pandas
    ```
    こんな感じで、仮想環境内にパッケージがインストールされます。

4. 仮想環境の無効化
    作業が終わったら仮想環境を無効にします。
    ```
    (myenv) $ deactivate
    ```
    これで仮想環境が無効化され、元の環境に戻ります。


## まとめ
venvを使うことで、プロジェクトごとに異なる環境を手軽に管理できるようになります。
依存関係の衝突を避けることができ、システム環境もすっきり保てます。
まだ使ったことがない人は、この機会にぜひ試してみてください！

より詳しい使い方を知りたい人は、venvモジュール公式ドキュメントを確認してください。
https://docs.python.org/ja/3/library/venv.html#module-venv
1/x+1/y=1/144,x>=yを満たす(x,y)の個数とx+yの総和「PASSLABO様の東大模試初見を、初見でChatGPT-3.5先生に聞きました。」(その1/2)をChatGPTとsympyでやってみたい。


・2024-06-16追加
旧タイトルに(その1)を追加しました。
1/x+1/y=1/144,x>=yを満たす(x,y)の個数とx+yの総和「PASSLABO様の東大模試初見を、初見でChatGPT-3.5先生に聞きました。」をChatGPTとsympyでやってみたい。

・なんだかスゴすぎる。
・出題者も点検しておられるかも。

# オリジナル
PASSLABO 様 (0:00〜12:25) **以下は、1:20　Let's go（レッツゴー）** からです。
＞やっぱり実験をして...

https://youtu.be/Xegn15FAmEE?t=80

# ChatGPT-3.5先生へ(1回目の繰り返し)
・？？？**実行する毎に、結果が異なります。**
　オリジナル様と同じ結果のときもあります。謎？
　私の聞き方が悪いかもです。 
・「日本語で」がないと、英文で出ることがあります。
```
1/x+1/y=1/144,x>=y
を満たす(x,y)の個数と
x+yの総和を求めよ
```

```
日本語で
```

**結果 いろいろ**
・...条件を満たすペアは23組あり、そのペアの 𝑥+𝑦x+y の総和は 68,599 です。 ​
・他

# ChatGPT-3.5先生へ(2回目)sympyで
```
sympyで
```

```python
import sympy as sp

# 変数の定義
x, y = sp.symbols('x y')

# 方程式の定義
equation = sp.Eq(1/x + 1/y, 1/144)

# y を x の関数として解く
solution_y = sp.solve(equation, y)

# ペアを格納するリスト
pairs = []

# x が 144 以上の整数の場合
for x_val in range(1, 144**2 + 1):
    if x_val >= 144:
        y_val = solution_y[0].subs(x, x_val)
        if y_val.is_integer and y_val <= x_val:
            pairs.append((x_val, int(y_val)))

# ペアの数を計算
num_pairs = len(pairs)

# x + y の総和を計算
sum_xy = sum(x + y for x, y in pairs)

# 結果を表示
print(f"ペアの数: {num_pairs}")
print(f"x + y の総和: {sum_xy}")
print(f"ペア: {pairs}")
```

???
ペアの数: 0
x + y の総和: 0
ペア: []

私は、ここまでです。




# ChatGPT-3.5先生へ(3回目)コメント様より
・？？？x,yの定義の整数、自然数がありませんでした。**本ページの(その2)を検討中です。**
```
1/x+1/y=1/144,x>=yを満たす(x,y)の個数とx+yの総和を求めよ
yがマイナスの場合がありますか？
```

# sympyで(オリジナル 様の方法を参考に)
・勉強中。私は理解できませんでした。
　私はアレ。１個しか浮かびませんでした。

# いつもの? sympyの実行環境と 参考のおすすめです。
[(テンプレート)](https://qiita.com/mrrclb48z/items/00dd08b0317069be9342)

# いつもと違うおすすめです。
UnrealEngineで特定のプラグインを使用していたら定数を定義してC++で利用できるようにする

UnrealEngineのプロジェクトのbuild.csで特定のプラグインが有効な場合に定数を定義してC++で利用してみたのでその内容を記録しておきます。

# 参照サイト

以下のサイトにあるように、uprojectのJSONファイルをパースしてプラグイン情報を取得してプラグインが有効になっているか判断しています。

https://forums.unrealengine.com/t/get-a-define-in-code-if-plugin-is-loaded-and-build-into-project/371418/7

# 試した環境

UE5.3.2

# 試した内容

以下のようにプロジェクトのbuild.csに追記しました。
using EpicGames.Coreの実体は、UnrealEngineソースのEngine/Source/Programs/Shared/EpicGames.Coreの中みたいでJSONパーサーなどのクラスが用意されているようです。

```csharp:build.cs
using System.Runtime.CompilerServices;
using UnrealBuildTool;
using EpicGames.Core; // <= 追加
using System;

public class CppBuildCsJsonTest : ModuleRules
{
	public CppBuildCsJsonTest(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
	
		PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });

		PrivateDependencyModuleNames.AddRange(new string[] {  });

        Configure(Target); // <= 追加
    }

    // 追加
	private void Configure(ReadOnlyTargetRules Target)
	{
        JsonObject RootObject;
        if (!JsonObject.TryRead(Target.ProjectFile, out RootObject))
        {
            throw new Exception(string.Format("{0} is not found", Target.ProjectFile.FullName));
        }

        JsonObject[] PluginObjects;
        if (!RootObject.TryGetObjectArrayField("Plugins", out PluginObjects))
        {
            return;
        }

        foreach (JsonObject PluginObject in PluginObjects)
        {
            string PluginName;
            PluginObject.TryGetStringField("Name", out PluginName);

            bool PluginEnabled;
            PluginObject.TryGetBoolField("Enabled", out PluginEnabled);

            if (PluginName == "OpenXR" && PluginEnabled)
            {
                PublicDefinitions.Add("OPENXR_ENABLED=1");
            }
        }
    }
}
```

以下のようなC++コードを用意しておくとプラグインが有効か判定できます。

```cpp
#pragma once

#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "MyUtils.generated.h"

UCLASS()
class CPPBUILDCSJSONTEST_API UMyUtils : public UObject
{
	GENERATED_BODY()
	
	UFUNCTION(BlueprintPure)
	static bool IsEnabledOpenXR() 
	{
#ifdef OPENXR_ENABLED
		return true;
#else
		return false;
#endif
	}
};
```

ただし、プラグインを有効・無効にしただけでは即座に反映されません。
プラグインの有効・無効を変更した後にVisualStudioでプロジェクトをビルドする必要があります。
単純にプラグインが有効化どうか判定するだけならもっと別の方法が良さそうですが、プラグインが有効な場合に依存する処理をして有効でない場合はしないといったC++のコードを書きたい場合には良さそうな気がします。
【入門】VPSで借りたubuntuをサクッとセキュリティ向上

# この記事について

本記事は自身の忘備録的な要素も強いですが、出来るだけ読み返し易いようにしたので、良ければ参考にしてください。

# 実例

以下からは、コマンドの実例を紹介していきます。基本的には順番通りに行うことができるように書きました。

大きくは以下の3つを行います。

・公開鍵認証のみをssh接続に利用するように変更
・sshのポート番号を変更
・ufw(ファイアウォール)の設定


## sshログイン
```
ssh <ユーザー名>@<IPアドレス> 
```

基本的なVPSに接続するためのコマンド


## userを追加

***目的***
rootユーザーを使うのは全ての権限を持ってることもあって危険だから、操作を行うためのユーザーを作成する。
```
sudo adduser <ユーザー名>
```




## userをsudoグループに追加
***目的***
sudoグループに追加することで、追加したユーザーにファイル変更などの権限を与えることができる。
```
sudo gpasswd -a <new_user> sudo
```


-aは追加を表すオプション
-dで削除などがある

## ssh鍵作成
***目的***
公開鍵認証を行うために作成する。
```
ssh-keygen -t rsa -b 4096 -C メールアドレス
```

-tで鍵のタイプ指定、-bでビット数指定する。
秘密鍵と.pubとついた公開鍵が作成される。
鍵の作成先を選べるけど、デフォルトなら~/.ssh以下に作成される。

## サーバーにssh鍵を登録


```
ssh-copy-id -i 公開鍵のパス <new_user>@<your_vps_ip>
```

デフォルトだと~/.ssh以下に作成された公開鍵のパスを指定


## パスワード認証の無効化
***目的***
パスワード認証は総当たりなどに弱くて安全性が低いから、作成した公開鍵認証のみでVPSに接続したい。

```
sudo nano /etc/ssh/sshd_config
```

でテキストエディタ開いて、以下に変更する
```
PasswordAuthentication no
```

## sshサービスの再起動
***目的***
sshサービスの変更を更新するために行う。

```
sudo systemctl restart ssh.service
```

## sshポート番号を変更
***目的***
sshはデフォルトでPort番号22が設定されてるが、攻撃の対象になりやすいから変更しておく。

```
cat /etc/services
```
に書かれていない1024~32767に書かれていないポート番号を適当に選ぶのが良い。

変更には、以下でテキストエディタを開いて

```
sudo nano /etc/ssh/sshd_config
```


```
#コメントアウト
#Port 22

<例：　10022に設定する場合>
Port 10022
```

のようにする。こうするとssh接続の際は以下のようになることを注意する。

```
ssh -p 10022 ユーザ名@IPアドレス
```

:::note warn
さくらVPSなどパケットフィルタが最初から存在する場合は、ポート番号がブロックされるから、パケットフィルタを外す必要がある。
外したら、自前でUFWといったファイアウォールをしっかりと設定する。
:::

## ufw(ファイアウォール)のステータス確認
```
sudo ufw status
```

デフォルトではinactiveになっており、起動していない。

## ufwで外部からの接続を許可する方法
***目的***
デフォルトでは外部からの接続は拒否されているはずなので、必要な通信プロトコルを許可する必要がある。

```
sudo ufw allow 通信プロトコル

<例: ssh>
sudo ufw allow ssh

ポート番号を変えているなら、以下のようにポート番号も指定する
sudo ufw allow 10022/ssh
```

## 回数制限付きで外部からの接続を許可
***目的***
総当たりでパスワードを入力することや、大量のアクセスを行う攻撃に対応できる。
```
sudo ufw limit 通信プロトコル

<例: ssh>
sudo ufw limit ssh

ポート番号を変えているなら、以下のようにポート番号を指定する
sudo ufw limit 10022
```
limitによる許可は、30秒に6回までの接続を許可する。
sshは多くの接続を普通は行わないので、limitによる許可が好ましい。

## ufwの起動

:::note warn
上記のssh接続の許可をしていないと、ssh接続が出来なくなるから注意する。
もしものために、ネットワークを経由しない、仮想コンソールなどのアクセス手段を確保する。
:::

```
sudo ufw enable
```

# おわりに

他にもsshコマンドでのログイン時に2段階認証をつける方法なども存在します。
ここに追加するかもしれませんが、興味がある方は調べてみてください。

# 個人的なメモ

### 特定のサービスの稼働状況を確認
```
sudo systemctl status サービス名
```


### 起動している全てのサービスのリストを確認

```
sudo systemctl list-units --type=service --state=running
```
【Unity】スクリプトのフォルダを変更したらFailed to find entry-pointsとかいうエラーが出てスクリプトが読み込めなくなった

# 症状
スクリプトはフォルダ内に存在していて、Unityからも確認できるがVisual StudioなどのIDEから参照できなくなる。
プロジェクトの再ビルドや再起動でも治らない。

# 結論
フォルダ名を"Editor"にしていた為。フォルダ名を変更するのが速い。

#
エラーから辿っていろいろ探ったけど原因がシンプルだったため、備忘録的な。
エラー自体はパスが間違っている～とかアセンブリがビルドされていない～とかそんなところ。
いろいろ調べていくうちに、凡ミスに気付いた。



Unity側がエディタースクリプトを扱うためにフォルダ名"Editor"を予約している。
そのため、扱うスクリプトによってはエラーとなることも。
同様に"Resources"フォルダや"Plugins"フォルダなども稀にですが、エラーが出る。

https://docs.unity3d.com/ja/2019.4/Manual/SpecialFolders.html



フォルダ名に"Editor"を用いたくて、IDEからでも参照できるようにするためにはアセンブリ定義など回避方法があるっぽいが
今回、自分のケースだとこのフォルダ名である必要はない為,
詳しく調べてない。
【勉強会資料】 大規模言語モデル入門 第2章 Transformer

[大規模言語モデル入門](https://amzn.asia/d/16Wzurj ) の輪読会を開催したので、発表に使った資料を一部修正して公開します。

# Transformerとは？
Googleが2017年に提案したニューラルネットワークモデルのアーキテクチャ。 
Transformer自体はモデルではなく、あくまでモデル内構造の１つ。

原著：[Attention Is All You Need](https://arxiv.org/abs/1706.03762)

# Transformerのざっくり背景
* Transformerはなぜ生まれたのか。
    * 今まで系列データ（文章など）の処理にはRNNが使われていた。
* RNNなどのSeq2Seqには、主に課題が２つあった。
    * 系列の位置情報を考慮しにくい（離れた位置との依存関係を考慮しにくい）
    * 学習の高速化が難しい。
* Transformerには３パターン存在するらしい
    * エンコーダのみモデル（BERTはこれ）
        * 主に使われるタスク：文章分類、クラスタリング、対話モデル
    * デコーダのみモデル（GPTはこれ）
        * 主に使われるタスク：文章生成、要約生成
    * エンコーダ&デコーダモデル
        * 主に使われるタスク：機械翻訳、text2code
* Transformerが出現する以前にこれらは存在していたモデルではある。

# エンコーダとデコーダ
* エンコーダとは？
    * シーケンスを高次元の特徴表現に変換する役割を持つ。
    * 文章入れるとただ数値の行列が出てくるイメージ。
* デコーダとは？
    * 主にシーケンスの生成を行う役割を持つ。
    * デコーダによって、文章が出てくる。
  
# エンコーダとデコーダを構成する仕組み
エンコーダとデコーダを構成には、下記のような手法が組み込まれている。

* エンコーダ
    * 入力トークン埋め込み(Word Embedding)
    * 位置符号化(Position Encoding)
    * 自己注意機構(Self Attention)
    * 加算&層正規化(Add&Layer Normalizationa)
    * マルチヘッド注意機構 < こいつがTransformerのミソ

* デコーダ
    * 入力トークン埋め込み(Word Embedding)
    * 位置符号化(Position Encoding)
    * 自己注意機構(Self Attention)
    * 残差結合&層正規化(Add&Layer Normalizationa)
    * フィードフォワード層
    * マルチヘッド注意機構 < こいつがTransformerのミソ
    * 交差注意機構(Cross Attention) < デコーダのみに存在する。

# 入力トークン埋め込み(word embedding)とは？
* トークンの意味をV×Dの行列で表現する仕組み。
    * Vは単語の数
    * Dは次元数
        * ここのD次元はハイパーパラメータなので、タスクに応じて適切に決める必要があるらしい。次元を増やすほど、表現が豊かになるので精度は上がる可能性が高まる？が、計算時間がかかる。
        * ちなみにBERTは768次元、GPT-3は2048次元らしい。

# 位置符号化(Position Encoding)とは？
* トークンの位置を表現する仕組み。
    * 正弦関数を使って位置符号を付与する。
* 正弦関数（sinとかcos）を使うと何がいいのか。
    * 相対的な単語の位置を表現しやすい。
    * 例えばpos=1とpos=10000の波形が全然ちがう。
    * つまり文脈的な関係性はほとんどないと捉えられる。

詳細な内容については、下記の記事がとてもわかりやすいです。

https://zenn.dev/attentionplease/articles/1a01887b783494

# 自己注意機構(Self Attention)とは？ 
* モデルが文脈を理解する仕組み
    * 例えば 「マウス🐭」と「マウス🖱️」の意味を判別するために使う。
* そもそもAttentionとはなんぞや？
    * Attentionは「重要な要素の重みを高くする機構」と理解すれば良さそう。
* QueryとMemory(Key, Value)が基本となる。
    * QueryによってKeyを検索し、Valueを取得する（Pythonのdictに近い）
    * このQueryとKeyを同じトークンで構成し、最終的にトークン間の関連性スコアを算出する。
    * QueryとKeyは異なる埋め込みが付与されるが、これは同じ埋め込みだと必然的にトークン自身が１番高くなってしまうことに起因する。

# マルチヘッド注意機構(Multi-head Attention)とは？
* Attentionを同時に処理するための仕組み。
    * Transformerのミソらしい。
* 何がスゴいのか。
    * 早く計算できる。
    * それぞれのヘッドが異なる特徴を学習し、文脈を理解するようになっている。
    * 通常のAttentionの学習では、長文扱うと精度がどんどん落ちていくらしい。

# 交差注意機構(Cross Attention)とは？
* 役割は自己注意機構と同じだが、エンコーダの情報をMemory(Key, Value)として使い、デコーダの翻訳文をQueryとして入力にいれる。

# 残差結合と層正規化とは？
* 両方とも学習を安定させるための仕組み
* 残差結合は勾配消失（勾配が小さくなりすぎること）を防ぐ。
* 層正規化は値が大きくなりすぎることによって訓練が不安定になることを防ぐ。

# フィードフォワード層
* 非線形活性化関数（ReLUなど）で非線形変換を行うことができる。
* 非線形だと複雑な関数をモデル化しやすいので表現力が上がる。

# ドロップアウト
* 一部のベクトルを学習に用いないようにして、過学習を防ぐ仕組み。

# 参考文献
- [大規模言語モデル入門](https://amzn.asia/d/3xTMT8o)
【考え方】ユーザー目線でコードを書くようになるまで

 

### はじめに

どうも、自社開発企業の SES 部隊として日々客先で業務をこなしているはずれと申します。未経験からエンジニアに転職し、だいたい 1 年半くらいが経ちました。  
今回は、私がプログラミングを始めた頃から、ユーザー目線でコードを書くようになるまでの経緯を振り返り、その重要性(個人の意見)等をお話ししたいと思います。

### この記事の対象者

- プログラミング未経験者
- プログラミング経験者でも、ユーザー目線での開発に興味がある方

### プログラミングにおける 3 つの要素

#### ① ユーザーの要件 ≒ アウトプット

ユーザーの要件を明確に理解することが最初のステップです。これは、何を実現したいか（アウトプット）を定義します。要件定義フェーズでは、ユーザーインタビュー、ユーザーストーリーの作成、機能要件のドキュメント化などが含まれます。これにより、どのような機能が必要か、どのような問題を解決するかが明確になります。

#### ② それに対しての前情報等 ≒ インプット

次に、その要件を実現するために必要なデータや情報（インプット）を特定します。これは、アプリケーションが処理する入力データや、外部システムから取得する情報、またはユーザーが直接入力する情報などです。このステージで、どのようなデータが必要で、どこからそれを取得できるかを決定します。例えば、ログイン機能を実装する場合、ユーザー名とパスワードが必要になります。

#### ③ インプットからアウトプットを作成する ≒ プログラミング処理

最後に、具体的なプログラミング処理を行います。このステージで、受け取ったインプットを処理し、要件に合わせたアウトプットを生成します。ここでは、アルゴリズムの設計、コーディング、テストが行われます。例として、受け取ったユーザー情報を認証し、アクセス権を決定する処理が挙げられます。

### 初心者の頃の私のアプローチ（②→③→①）

#### やっていたこと

プロジェクトに入りたてのプログラミング初心者の頃は、主に「インプットからアウトプットを作成する」ステージから開発を始めていました。コーディング楽しい！処理が動いたヤッター！状態で、ユーザーの要件を理解することを後回しにしていました。

#### 結果

- 無駄の多いコードの量産
- ユーザーの要件を満たしていない
- ユーザーからのフィードバックが多い（戻り工数の発生）

そりゃもう、たくさんの指摘を受けました(泣)

### 今の私のアプローチ（①→②→③）

#### やっていること

今は、ユーザーの要件を理解することから開発を始めるようにしています。結局のところ、ユーザーが求めているものを提供することが開発の目的です。そのため、ユーザーの要件を理解し、それに対して必要なインプットを特定した上で、プログラミング処理を行うようにしています。

#### 結果

- ユーザーの要件を満たすための最小限のコードを書くことができる
- ユーザーからのフィードバックが減った（戻り工数の削減）
- ユーザーの満足度が向上
- 自分の評価も上がった！

### 学び

- 結局のところユーザーが求めているのはアウトプットのみ
- アウトプットを実現するための最小限の処理を行うことが重要
- エンジニアの自己満足でコードを書くのは厳禁

### おわりに

ユーザー目線でコードを書くことの重要性について、私なりの考え方をお話しました。これからプログラミングを始める方、またはユーザー目線での開発に興味がある方にとって、少しでも参考になれば幸いです。また今話した内容は、私の個人的な意見です。他の方の意見も参考にして、自分なりの考え方を見つけていただければと思います。そして私にもっとユーザー目線でコードを書くためのヒントを教えてください！
YOLOv9がMIT Licenseで再実装中らしい

X(旧Twitter)を徘徊していたら以下のポストを目にしました。

https://x.com/UnaNancyOwen/status/1771040420648419551

> YOLOv9をMIT Licenseで再実装

https://t.co/7eUsI0Jz8Y

なんですって？？？需要ありまくりじゃないですか！！！
※個人の感想です。

GitHubとぶと絶賛開発中のようですね。

OSSのライセンスについてここで言及する気はありませんが、最近のYOLOはライセンスがGPL-3.0やAGPL-3.0ばかりで嫌になっていました。

制約が多いので業務では採用しづらい、、、というのが私の現状です。

そんな中でMITライセンスでの再実装ということで今後注目していきたいと思います。
moonrepoのproto toolsのtomlを30秒で作る方法

## 前提

gRPCのprotoではなく、moonrepoのproto toolsの事を指しています

https://moonrepo.dev/docs/proto/tools

githubにアーティファクトがある前提です.

### 1. assets一覧を出す

```sh
gh release view v4.44.1 --repo mikefarah/yq --json assets | pbcopy
```

## 2. ChatGPTでmonnrepo-proto-tools-toml-creatorに内容を貼り付ける

https://chatgpt.com/g/g-HM8WnI0OZ-monnrepo-proto-tools-toml-creator

![CleanShot 2024-06-13 at 10.54.07@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141711/3bf25a48-91a0-cf5e-37a2-cf08d8411e85.png)

以下のようなtomlが生成されます。以上で完了です.

```toml
name = "neovim"
type = "cli"

[platform.linux]
download-file = "nvim-linux64.tar.gz"
checksum-file = "nvim-linux64.tar.gz.sha256sum"

[platform.macos]
download-file = "nvim-macos-{arch}.tar.gz"
checksum-file = "nvim-macos-{arch}.tar.gz.sha256sum"

[platform.windows]
download-file = "nvim-win64.{ext}"
checksum-file = "nvim-win64.{ext}.sha256sum"

[install]
download-url = "https://github.com/neovim/neovim/releases/download/v{version}/{download_file}"

[install.arch]
aarch64 = "arm64"
x86_64 = "x86_64"

[install.ext]
msi = "msi"
zip = "zip"

[resolve]
git-url = "https://github.com/neovim/neovim"
```
「ほぼ」未経験エンジニアがプログラミング嫌い意識をなくすまで



# 自己紹介
初めまして。新卒「ほぼ」未経験エンジニアのパン派です。

# 「ほぼ」と付けたわけ
実は大学時代、プログラミングには触れていました。ただ当時向いてないと思い早々に諦めた経緯があります。
それがなぜか今エンジニアとして働くことになっています。しかも割とそのことを前向きに捉えており、楽しく勉強しています。
 **「プログラミングに興味あったけど才能ないなー」** と諦めようとしている方や、 **「どうやったらプログラミングに魅力を感じてもらえるかわからない！」** と思っている方の参考になればいいなと思っています。


# なぜ苦手意識があったのか
 **1. 周囲に実力者がたくさんいたから** 
「自分よりはるかにできる人がいる」って事実を知ると、「今から始めてもしょうがない」とか「自分には才能ない」って思いこんでしまうことって、プログラミングに限らずあると思います。**触れないことで「できない」のではなく「やっていない」ことにする** って、結構みんなやっていることなんじゃないかと思っています。

 **2.プログラミングは「理系の独壇場」だと思っていた** 
 理系の方が活躍できるフィールドであること自体は間違いではないと思うのですが、「数学や物理ができないとスタート地点にすら立てない」と思っており、両方不得意だからだめだなー。と思っていました。
さらに「その前の段階をすべて理解しなければ次の段階に進めない」と思い込んでおり、当然全部を理解できているわけなどないので匙を投げるといったことが多発しました。

 # 苦手意識がなくなった理由
  **1.人は人、自分は自分。で折り合いがつけられるようになった** 
  「オリンピックには出場できないから運動しない！」とはならないですよね。どんなクオリティであれ、勉強することに価値はあります。
  （そのスタンスを認めてくれる職場環境であることも大きいと思います。ありがたい限りです。）

 **2.プログラミングって結構言語学習じゃない？と気づいた**

外国語を学習するときって、
+ 間違ってもいいからまず喋ってみる
+ 手本の例文から文法や品詞を推察する

あたりが重要だと思っているのですが、これってかなりプログラミング学習にも通じるところがあるなと。
+ 間違ってもいいからまずコードを書いてみる
+ 手本のコードから文法や意図を推察する

みたいな。

もちろんアルゴリズム考えたりとか、数学っぽいこと考えなきゃいけなかったりする瞬間はあると思うんですが、そういう理系っぽいことより先に **「なんでもいいからプログラミング言語で喋って（書いて）みて！」** と言われていたら、文系の私はまた違った意識で取り組めたのかなとも思います。
（とはいえ「言語学習が嫌い！」という方もしばしば見かける気がするので、この辺りはなんとも言い難いですが……）

 **3.（余談）意外に「ちょっとやってた」意味があった**
意外に **「最後に;を付ける」** とか **「変数という概念がある」** という超基礎を知っているだけでもだいぶ違うなと。
英語だったら文頭は大文字にするとか、慣れちゃえば当たり前なんですけど最初のうちは混乱しますよね。そういう「超基礎レベルのつまづき」を結構減らせていたと思っています。
もし初学者でつまづいている人がいたら、案外このあたりの「超基礎」を徹底して覚えるだけでもエラーの数は減らせるし、コードが読めるようになるのではないかと思います。

# 今の自分なら過去の私になんて言う？
これらを踏まえて、プログラミング向いてないと思っていた当時の私に今ならなんと声をかけるか考えてみました。

+ 確かに他人と比較してプログラミングの経験もセンスもないかもしれないけれど、それでも勉強したっていいんだよ。他人と比較してできないことは、それをやってはいけない理由にはならないよ。
+ プログラミングって案外言語学習だから、とりあえず触って、意味が分からなくても「喋って」みるのが大事だよ。
+ （それはそれとして、未来の私が後悔しているので数学はちゃんと勉強してね）

# おわりに
どこかで「プログラミングの才能なんかないよ！」と思っている誰かに届けばいいなと思いながら書きました。私もまだまだ勉強することしかない身なのでがんばろうと思います。
【第1回】せや！自宅サーバーと業務用ルーターを導入したろ！

皆さんは自宅サーバーという言葉を聞いたことはありますか？
プログラマーなら一度は聞いたり調べてみたことがあると思います。

そして私は今年に元旦こう思いました。

**せや！自宅サーバーと業務用ルーターを導入したろ！**
↑は？

## ことの発端
私は元旦にばあちゃんちに帰省しいろいろと調べ物をしていました。
そしたらYahoo!フリマーのクーポンがあることに気づきました。
お年玉ももらったことだしさあ何を買おうかなー

「YAMAHAのRTXほしい！！」

と思って調べましたがいいものは結構な値段がすることが分かり色々調べると国内メーカーではYAMAHAのRTXとNECのUNIVERGEの二大勢力(?)があることが分かりました。

「しゃーねーNECで妥協するかー」

と思い調べるとIX2105という型落ち機種が安いことに気づきました。

「これLANポートもちょうどよくてコンパクトだしちゃんと1000BASE-TXでギガビット対応してんじゃん」

明らかにばあちゃんちでやることではないですね()
ということで...

## 無事IX2105を購入
![1718181820982.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518724/ea060a7d-c297-31c6-d917-5e6ea29a816c.jpeg)

Yahoo!フリマにて3,000円程で無事購入。
うっひょー！！

## 悲劇
そして設定しようと思いPCへLANケーブルを設定しIPなどを手動で設定。
そしてかっこよく「192.168.1.1」と入力し爆音でEnterキーを押すものの...

「あれ？ページが来ない」

何度もリセットしたものの一向に動かない
調べてみるどうやらWebの画面はデフォルトでは無効らしい。

一般家庭にコンソールケーブルなんかないので仕方なく一番安いやつを購入。(LANからUSBに直で変換するうやつ)

## 設定完了☆彡
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518724/61876245-8137-3310-3ac2-c38485e2626d.png)
いろいろとトラブルはあったものの無事にSoftbank光でPPPoE IPv6することに成功。
光BBユニットとは別のIPが振られるのでポート開放とかしても大丈夫そう。
(光BBユニットはいちいち再起動いるけどIX2105は**業務用**なので保存するだけでおｋ)

## 最後に
この話は第2話へと続く...(明日公開予定)
intra-mart概要

# intra-mart製品群
　ローコード開発＆業務プロセスのデジタル化・自動化ツールのこと
　大きな製品としては以下５つ
## ・Accel Platform
 　　⇒システム共通基盤　（フレームワークの提供、それを使ったローコード開発）
## ・Accel Applications
 　　⇒業務アプリケーション（勤怠管理とか実際のアプリケーション機能）
## ・Accel Mart
 　　⇒クラウド型システム共通基盤
## ・intra-mart DPS
 　　⇒業務支援アプリケーション（勤怠管理とか実際のアプリケーション機能（クラウド版））
## ・intra-mart Procurement Cloud
 　　⇒クラウド型購買システム


# ツール群
## IM-BIS
　　IM-BISとは、画面作成ツール、ワークフロー、BPM（Business Process 　Management）、BAM（Business Activity Monitoring）、
　　外部連携のData Mapperなどの統合や機能拡張を圧倒的な低コストで容易に実現するソフトウェアツール。
　・ビギナーズガイド
　　https://document.intra-mart.jp/library/bis/public/bis_beginners_guide/index.html
　・システム管理者ガイド
　　https://document.intra-mart.jp/library/bis/public/bis_administrator_guide/index.html
　・業務管理者ガイド
　　https://document.intra-mart.jp/library/bis/public/bis_manager_guide/index.html
　・構成要素
　　https://document.intra-mart.jp/library/bis/public/bis_setup_guide/texts/flowchart/index.html
　　・データベース
　　　⇒Oracle、SQLServer、PostgreSQLが使用可能
　　・APサーバー
　　　⇒Resin
　　・Webサーバー
　　　⇒Apache、IIS
　・以下のIM-WorkflowとIM-FormaDesignerとの関係性
　　https://document.intra-mart.jp/library/bis/public/bis_administrator_guide/common_module/texts/about/index.html

## IM-Workflow（IM-BISのなかに含まれる）
　　ワークフロー定義を実装するためのツール

## IM-FormaDesigner（IM-BISのなかに含まれる）
　　画面を作るためのツール
　　・開発者ガイド
　　　https://document.intra-mart.jp/library/forma/public/forma_appli_maker_guide/introduction.html

## IM-LogicDesigner
　　コーディングせずにロジックを実装できるツール
　　作ったものは「ロジックフロー」と呼ばれる部品として利用できるようになる

## IM-BPM
　　業務プロセスを可視化するためのツール
　　これを使ってアプリを作るとかではなく、システム導入時等の業務フローの整理や見直しに使う

## IM-Repository
　　テーブル定義を作成したりするツール

## IM-Juggging
　　Warを固めるツール

# その他メモ
　・BISフローとワークフローの違い
 　　申請・承認を行う場合には「ワークフロー」を使って、そうでない場合には「BISフロー」を使う
　・フォーム画面の確認方法
 　　「IM-BIS」⇒「一覧」で対象WFを開き、「アプリ」⇒「フォーム設定」⇒「編集」から「フォーム一覧」タブで確認が出来る
　・ワークフローの状況に応じた処理を入れるには
 　　「IM-BIS」⇒「一覧」で対象WFを開き、「アプリ」⇒「フォーム設定」⇒「編集」から「ユーザープログラム一覧」タブで確認が出来る
　・分岐のルールで、共通のルール定義を使う
 　　「コンテンツ定義」で、対象のワークフローを開き、「ルール」タブで新規作成をクリックして名前を定義する。実体は、共通のルール定義を検索する。コンテンツ定義でまず設定することで、このルールが使用可能になる。
   今度は、「フロー定義」で「ルート詳細」タブを開き、ノードをダブルクリックすると分岐のルール設定が可能になる。
　・ノードのコピペについて
  　　コピペはできるが、以下は含まれないので再度設定が必要
  　　・IM-BISの画面設定（コピー元の画面を「共有」して、コピー先の画面で「貼り付け」）
  　　・フロー定義のノード設定で、処理設定
  　　・分岐の設定
Login Pageでパスワードの表示/非表示を切り替えるアイコンボタンを実装するサンプル

## パスワードの表示/非表示を切り替えるアイコンボタンを実装する
### 以下のようにHTMLとJavaScriptを組み合わせて実装します。以下は、ログイン画面でパスワードの表示/非表示を切り替える方法を示す例です。

```login.html
<!DOCTYPE html>
<html lang="jp">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login Page</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
    <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
    <div class="container mt-5">
        <div class="row justify-content-center">
            <div class="col-md-4">
                <h2>Login</h2>
                <form id="login-form">
                    <div class="mb-3">
                        <label for="username" class="form-label">Username</label>
                        <input type="text" class="form-control" id="username" required>
                    </div>
                    <div class="mb-3">
                        <label for="password" class="form-label">Password</label>
                        <div class="input-group">
                            <input type="password" class="form-control" id="password" required>
                            <button class="btn btn-outline-secondary" type="button" id="toggle-password">
                                <i class="bi bi-eye-slash" id="toggle-password-icon"></i>
                            </button>
                        </div>
                    </div>
                    <button type="submit" class="btn btn-primary">Login</button>
                </form>
            </div>
        </div>
    </div>
</body>
</html>
<script>
$(document).ready(function () {
    $('#toggle-password').click(function () {
        const passwordInput = $('#password');
        const passwordIcon = $('#toggle-password-icon');
        const type = passwordInput.attr('type') === 'password' ? 'text' : 'password';
        passwordInput.attr('type', type);

        // Toggle the icon class
        if (type === 'text') {
            passwordIcon.removeClass('bi-eye-slash').addClass('bi-eye');
        } else {
            passwordIcon.removeClass('bi-eye').addClass('bi-eye-slash');
        }
    });
 });
</script>
```
### 実施例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509696/fa8da5c7-435f-928d-83b0-a44957c60580.png)
Difyを用いた、URLからテキスト抽出を行うアプリケーション

# はじめに
今回は、Difyを用いてURLからテキスト抽出を行うアプリケーションを実行した。

Difyの詳細については、以下の通りである。

https://dify.ai/jp

以下に、導入を示す。

# 導入
今回は「ワークフロー」のタイプで作成した。
アプリケーションの全体像は以下のようになっている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806967/93b30b8d-0cff-0b2c-5be2-f5b01dfe19f2.png)

開始の部分では、変数名を input とした。
ラベル名を、 メッセージを入力してください。URLが入力されれば、そのURLのテキストを抽出し、出力します。 とした。
最大長は256にした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806967/cf0d4e53-4985-c65e-485f-0f0ffeff4468.png)

質問分類器の部分では、開始部分の変数inputに、
①URLが入力された場合
②URL以外の情報が入力された場合
の2つの場合をLLMが分類し、それぞれ処理を実行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806967/999de074-0af7-7d18-62c6-eb0e0bd5d3b0.png)

①URLが入力された場合
今回はURLからテキストを抽出するために、JinaReaderを実行した。
JinaReaderは、指定されたURLからメインのテキストを抽出することができるツールである。

https://medium.com/@elmo92/jina-reader-transforming-web-content-to-feed-llms-d238e827cc27

開始部分の変数inputを入力変数に入力するだけで、URLからテキストを抽出することができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806967/7ade32f6-4a47-fdd5-a286-cc2a5cf1a369.png)

JinaReaderでテキストを抽出し出力した場合、出力結果は以下のようになる。
なお、URLは以下のサイトを使用した。

https://www.obutsudan-murata.com/wp-content/uploads/2017/12/pdf_sample.pdf

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806967/9e45c231-18af-35b8-1dfa-e6db900624f4.png)

この出力結果をより分かりやすく表示するために、LLMを使用する。
USERの部分に、 {x}textで抽出されたテキストのみを出力して と入力する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806967/043feb2f-515d-c98e-83ed-e2ef86c9b18e.png)

終了部分では、LLMによって得られた回答を出力する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806967/8a033247-09fb-d4db-689d-251ee64810c8.png)


②URL以外の情報が入力された場合
開始部分の変数inputでURL以外の情報が入力された場合は、入力された質問に答えてもらう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806967/539fba78-3e62-7680-9efe-2dad3ef775a0.png)

終了部分では、答えてもらった質問を出力する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806967/8d8c7581-c6c6-0b14-fbe7-d63946b1d43d.png)

# 実行結果
①URLが入力された場合
入力されたURLのテキストを抽出し、出力する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806967/c89b7cf5-a0c8-016c-8146-b738f8bc31c0.png)

②URL以外の情報が入力された場合
入力された質問に答える。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806967/26e05d03-4e9b-16ee-ba65-484f604794dd.png)


# まとめ
今回は、Difyを用いてURLからテキスト抽出を行うアプリケーションを実行した。
今後はこの機能の他にも、URLの情報の概要を出力し、プレゼンテーションの原稿を作成するといった機能を持つようなアプリケーションを作成していきたい。
【Python】PEP 8を読んだら新たな発見があった件

Pythonのコーディング規約として公開されているPEP 8に今更ながら目を通すと理解が深まりました。

https://pep8-ja.readthedocs.io/ja/latest/

(需要はないと思いますが) 私視点で勉強になったことをまとめます。

## 式や文中の空白文字

### スライス

> スライスではコロンは二項演算子のように振る舞います。よって、(コロンは優先度が最も低い演算子として扱われるので)両側に同じ数(訳注: 無しでも可だと思われる)のスペースを置くべきです。拡張スライスでは、両側に同じ数のスペースを置かなければなりません。例外: スライスのパラメータが省略された場合は、スペースも省略されます。

```python
# 正しい:
ham[1:9], ham[1:9:3], ham[:9:3], ham[1::3], ham[1:9:]
ham[lower:upper], ham[lower:upper:], ham[lower::step]
ham[lower+offset : upper+offset]
ham[: upper_fn(x) : step_fn(x)], ham[:: step_fn(x)]
ham[lower + offset : upper + offset]
```

```python
# 間違い:
ham[lower + offset:upper + offset]
ham[1: 9], ham[1 :9], ham[1:9 :3]
ham[lower : : step]
ham[ : upper]
```

私はスライスの左にスペースなし、右にスペースを入れるということをしていたような気もするので反省ポイント。

### 優先順位の違う演算子

> 優先順位が違う演算子を扱う場合、優先順位が一番低い演算子の両側にスペースを入れることを考えてみましょう。入れるかどうかはあなたの判断にお任せしますが、二つ以上のスペースを絶対に使わないでください。そして、2項演算子の両側には、常に同じ数の空白文字を入れてください。

```python
# 正しい:
x = x*2 - 1
hypot2 = x*x + y*y
c = (a+b) * (a-b)

```

```python
# 間違い:
x = x * 2 - 1
hypot2 = x * x + y * y
c = (a + b) * (a - b)
```

これはよくやってしまいます。大反省。

## 末尾にカンマを付けるべき場合

### 要素が一つのタプルを作るとき

> 末尾にカンマを付けるかどうかは、通常は任意です。但し、要素数がひとつのタプルを作るときは例外的に必須です。混乱を防ぐため、要素数がひとつのタプルを作るときは、(技術的には冗長ですが) 括弧で囲むことを推奨します。

```python
# 正しい:
FILES = ('setup.cfg',)
```

```python
# 間違い:
FILES = 'setup.cfg',
```

ここまではちゃんとできていたのでセーフ。

### 繰り返し展開されることが期待される場合や、バージョン管理システムを使っている場合

> 末尾のカンマは冗長ですが、便利な場合もあります。たとえば値や引数、もしくはimportされた値のリストが繰り返し展開されることが期待される場合や、バージョン管理システムを使っている場合です。それぞれの値(など)を一行にひとつずつ置き、末尾にカンマをひとつ追加し、その次の行を 閉じ括弧/角括弧/中括弧 で閉じるというのがひとつのパターンです。しかし、区切りの終わりを示す目的で、同じ行の末尾にカンマを付けることは意味がありません(但し、既に示した、要素数がひとつのタプルの場合は除きます)

```python
# 正しい:
FILES = [
    'setup.cfg',
    'tox.ini',
    ]
initialize(FILES,
           error=True,
           )
```

```python
# 間違い:
FILES = ['setup.cfg', 'tox.ini',]
initialize(FILES, error=True,)
```

引数やリスト等の末尾にカンマを付けるのはよく見ますし、私自身もやっていましたが理由は把握できていませんでした。
バージョン管理ツールについての言及はなるほどな～と思いました。

### docstrings

TODO: PEP 257を読む！

https://peps.python.org/pep-0257/

## まとめ
今回挙げていないことも含めPEP 8はPythonを使っている人であればまず目を通すべきものであるなと感じました。(コーディング規約だしそれはそうなのですが…)

時間を作ってdocstrings (PEP 257) の方も読んでみようと思います。
JavaScript での F検定 の実装

# Reactive stat 内部の F検定の実装 です

F検定は、2つのグループの分散が等しいかどうかを検証するために行います。この記事では、F検定の概要と、JavaScriptでの実装方法を説明します。

## はじめに

弊社では **[ブラウザだけで使える無料統計ソフト Reactive stat](https://www.emuyn.net/stats)** を提供しています。
信頼性の高い R で統計解析し、その結果を AI が解説します！
その背景には、統計に苦労している医療者の助けになりたい、という気持ちがあります。
最終的な統計解析は R で行うのですが、レスポンスとサーバー負荷の改善のため、一部の統計計算はブラウザ内で行っています。
そのうち、汎用性の高い部分を共有させていただきたいと思います。
できるだけ R の出力と整合性を持つように javascript をインプリメントしてあるので、参考になれば幸いです。

## 使用したライブラリ

このコードでは、jStatライブラリを使用しています。jStatは、JavaScriptで統計計算を行うための便利なライブラリです。
jStatの詳細については、[公式ドキュメント](https://github.com/jstat/jstat) を参照してください。
全関数の一覧は [jStat v1.9.3 Documentation](https://jstat.github.io/all.html) を参照してください。

## F検定の概要

F検定は以下の手順で行います：

### 帰無仮説と対立仮説の設定
- $H_0$: $\sigma_1^2 = \sigma_2^2$ (2つの母分散は等しい)
- $H_a$ または $H_1$: $\sigma_1^2 \neq \sigma_2^2$ (2つの母分散は等しくない)
### F値の計算
F値は以下の式から計算されます: $F = \frac{{s_1}^2}{{s_2}^2}$
ここで、
- ${s_1}^2$ は1つ目のサンプルの標本分散
- ${s_2}^2$ は2つ目のサンプルの標本分散
### p値の計算と帰無仮説の評価
計算されたF値と自由度をもとに、p値を求めます。これは、観測されたF値以上の値が帰無仮説のもとで得られる確率です。通常、p値が事前に設定した有意水準（例えば、0.05）以下である場合、帰無仮説を棄却します。

## コード

ライブラリ込みの html にしてありますので、
[jsfiddle](https://jsfiddle.net/) などにコピペして簡単に試せます。

```html:html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>F-test</title>
  <script src="https://cdn.jsdelivr.net/npm/jstat@latest/dist/jstat.min.js"></script>
</head>
<body>
  <h1>F-test Example</h1>
  <p>Check the console for the result.</p>
  
  <script>
    // F検定
    function ftest(groupA, groupB) {
        const varA = jStat.variance(groupA, true); // true は不偏分散を取得
        const varB = jStat.variance(groupB, true);

        // サンプルサイズ
        const n1 = groupA.length;
        const n2 = groupB.length;

        // F統計量の計算
        const fscore = Math.max(varA, varB) / Math.min(varA, varB);

        // 自由度の計算
        const df1 = varA > varB ? n1 - 1 : n2 - 1; // 分子の自由度
        const df2 = varA > varB ? n2 - 1 : n1 - 1; // 分母の自由度

        // p値の計算
        const p = 2 * jStat.ftest(fscore, df1, df2, false);

        return p;
    }

    // サンプルデータ
    const group1 = [85, 90, 92, 87, 99];
    const group2 = [80, 82, 78, 83, 79];

    const pValue = ftest(group1, group2);
    console.log("F-test p-value: ", pValue);
  </script>
</body>
</html>
```

## 検証用 R コード

[rdrr](https://rdrr.io/snippets/) にコピペして簡単に試せます。

```R:R
# F-test

# サンプルデータ
group1 <- c(85, 90, 92, 87, 99)
group2 <- c(80, 82, 78, 83, 79)

# F検定を実行
result <- var.test(group1, group2)

# 結果の表示
print(result)
```

## 注意点

- このコードは、jStatライブラリに依存しています。jStatを読み込まないと動作しません
- 浮動小数点数の計算では、わずかな誤差が生じる可能性があります
- F検定は、データが正規分布に従っていることを前提としています。データが正規分布に従っていない場合、結果の解釈には注意が必要です

## 最後に

コードの内容はよく吟味し、R との食い違いが極力ないように気を付けていますが、もし間違いに気づかれた場合には指摘していただけますとありがたいです。

ただ、Chat GPT に読ませてその出力を検証もせず「問題があるので修正します」として貼り付けられると、他の方を混乱させてしまうのと、弊社の製品に対する信頼を損ねることにもつながりかねませんので、どうかそのようなことのないようにお願いいたします。

検証のための R のコードもつけてありますので、ご活用いただけますと幸いです。
PHPを使ってみよう：動的ウェブ開発の第一歩

# PHPの基礎

こんにちは、皆さん！今日は、PHPの基礎について一緒に学んでみましょう！PHPは、ウェブ開発でよく使われるサーバーサイドのプログラミング言語です。内定先の企業でもこの言語を使っていくので今回はPHPの基礎についてまとめてみようと思います。

## PHPって何？

まず最初に、PHPって何か知っていますか？PHPは「Hypertext Preprocessor」の略で、動的なウェブページを作成するための言語です。例えば、ログインフォームや掲示板、ショッピングカートなど、ユーザーが操作するインタラクティブなウェブページを作るのに使われます。

## PHPの基本構文

PHPのコードは、通常はHTMLの中に埋め込まれます。PHPのコードブロックは、`<?php ... ?>` というタグで囲まれます。さっそく簡単な例を見てみましょう。

```php
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>PHPの基本</title>
</head>
<body>
    <h1>こんにちは、世界！</h1>
    <?php
        echo "これはPHPで書かれたテキストです！";
    ?>
</body>
</html>
```
## 変数とデータ型
PHPでは、データを保存するために変数を使います。変数は、$ 記号で始まります。たとえば：
```php<?php
    $name = "太郎";
    $age = 25;
    echo "こんにちは、" . $name . "さん！あなたは" . $age . "歳ですね。";
?>
```
## 条件分岐
PHPでは、条件に応じて異なる処理を行うことができます。これを条件分岐と呼びます。if 文を使って条件分岐を行います。
```<?php
    $score = 80;

    if ($score >= 90) {
        echo "素晴らしい！あなたは優秀です！";
    } elseif ($score >= 70) {
        echo "よく頑張りました！";
    } else {
        echo "もう少し頑張りましょう！";
    }
?>
```
このコードでは、$score の値に応じて異なるメッセージが表示されます。90点以上なら「素晴らしい！」、70点以上なら「よく頑張りました！」、それ以外なら「もう少し頑張りましょう！」となります。

## ループ
同じ処理を繰り返し行いたい場合、ループを使います。PHPでは、for ループや while ループを使って繰り返し処理を行うことができます。
このコードでは、$name という変数に「太郎」という値が、$年齢 という変数に25という値が入っています。echo を使って、これらの変数をテキストの中に組み込んでいます。
```<?php
    for ($i = 1; $i <= 5; $i++) {
        echo "これはループの中の処理です。現在のカウントは" . $i . "です。<br>";
    }
?>
```
このコードでは、1から5までの数字を順番に表示します。for ループは、指定した回数だけ繰り返し処理を行います。

## 終わりに
今回はPHPの基本について簡単に紹介しましたが、実際に手を動かしてみることが一番の学習方法です。ぜひ、自分でもコードを書いて試してみてくださいね！
IBMCloud VRFの有効化(セルフサービス)

## 概要
IBMCloudでアカウントのVRF (Virtual Routing and Forwarding) を有効化するには
今までの場合、サポートケースを作成してVRFの有効化を依頼する必要がありました。
しかし、現在は利用者の操作のみで有効化できるようになっています。
今回はこれについて実際に実施してみる。

## 手順の説明
操作方法については下記のページに記載されている。
[コンソールでの VRF の有効化](https://cloud.ibm.com/docs/account?topic=account-vrf-service-endpoint&interface=ui&locale=ja#vrf)


以下注意事項

:::note alert
VRF を有効にすると、アカウントのネットワーキングが永続的に変更されます。 アカウントおよびリソースへの影響を理解しておく必要があります。 VRF を有効にした後に無効化することはできません。
:::

VRF を有効にする場合:

    1.コンソールで、**「管理」 > 「アカウント」と進み、「アカウント設定」**をクリックします。
    2.「Virtual Routing and Forwarding」 に移動し、 「オン」 をクリックします。

:::note info
ほとんどのアカウントでは、このアクションにより、プライベート・ネットワークが即時に VRF に変換されます。 一部のアカウントでは、 IBM Cloud サポートとの調整が必要になる場合があります。 サポート Case を作成するには、以下の手順を実行します。
:::

## 実際にやってみた
IBMCloudコンソールにログインする。

**管理** -> **アカウント**を選択
![貼り付けた画像_2024_06_13_10_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/5f208d84-1960-5bbf-c430-6ec4de1da6b8.png)

**アカウント設定**を選択
![貼り付けた画像_2024_06_13_10_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/49af6f23-3f7a-4004-244e-7346fb7cdb64.png)

画面をスクロールすると、「Virtual Routing and Forwarding: オフ」のエリアがある
現在の状態が「オフ」となっており、その下には「オン」にするためのボタンが表示されている。
![貼り付けた画像_2024_06_13_10_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/19e8588d-fb99-d3c7-458b-8b43d3352a79.png)

有効化するため、「オン」を選択
![貼り付けた画像_2024_06_13_10_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/9ee81fb3-0c46-f641-dd47-3c37e8677011.png)

確認画面が表示される
<font color="red">有効化すると元に戻せない</font>事、VRF有効化に伴い<font color="red">ネットワークが一時停止する可能性がある</font>ことに注意し✅をつけ、送信を選択
![貼り付けた画像_2024_06_13_10_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/783c9e84-92d9-cda8-08d3-f9d09c53ed69.png)

失敗した場合、は下記の通りAccess Deniedになるためサポートケースを起票する
（アカウントタイプLiteプラン（無料）だとできない）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/76525d48-e7fa-406f-5bc9-abeaf11151e1.png)

成功した場合、オンの画面に切り替わる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/fdc20c67-a611-694b-629c-159b341da9bc.png)
[備忘録]　読んだネットの記事 (FA業界) ver.3


# 備忘録

"“首をなが～くして”業務DXロボが設備点検、半導体工場で年内にも実運用へ"
https://monoist.itmedia.co.jp/mn/articles/2406/12/news080.html

[備忘録]
- 設備点検の自動化と点検で収集したデータの分析を通した設備運用の効率化を目的
- 工場内，湿度などの環境データをメーター自動読み取りサービスで取得
    - 収集されたデータはグラフ化される
- ロボットがランプの点灯などに異常を察知した場合は自動で通知を行う

"超大型加工機9台が3台に、DMG森精機が新設の第3精密加工工場が見せた工程集約"
https://monoist.itmedia.co.jp/mn/articles/2405/10/news074.html

[備忘録]
- 内製化や工場集約による品質向上，生産性向上を推進するために第3精密加工工場を新設
- 他社製の大型5面加工機5台と大型研削盤4台の合計9台を3台のDMU 1000 SEに置き換える
    - 加工時間の短縮に繋がる
- ストッカーへの投入，取り出しなどのワードハンドリングは自律走行ロボットが行う
    - ボールネジの工程集約ではロボット付きAMRがワークを出し入れ

"TDKがエッジAI搭載センサーモジュールによる予知保全ソリューションを提供へ"
https://monoist.itmedia.co.jp/mn/articles/2405/13/news070.html

[備忘録]
- 　i3 CbM Solutionは、小型センサーモジュールとネットワークコントローラー、ソフトウェアで構成
    - 　pcに接続したネットワークコントローラーが各モジュールと通信を行う
    - 　専用ソフトウェアがデータ収集やAI学習，データ監視の一連のプロセスを構築
    - 　振動や温度のセンサーとエッジAI（人工知能）が搭載されている
    - 　ワイヤレスメッシュネットワークに対応
    - 　機械や設備に設置した同モジュールがデータの取得と状況変化の判断を行う
        - 　リアルタイムでの状態監視が可能になる
kintoneのフィールド要素をマウスアウト時だけマスクする方法

# はじめに

サイボウズ株式会社が提供しているkintoneのレコード閲覧時のフィールドマスクです。

リモートワークや外出先でデータ閲覧時に、ショルダーハッキングを防ぐために作成しました。

## 表示イメージ


### マウスオーバー時
![139612134-e4aae33b-2862-4763-a13b-2522cfea6102.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394381/a3ad0936-f24a-fdd6-0fc4-0424d1b1e908.png)

### マウスアウト時
![139612128-754766f9-8d56-4073-87db-757a4b2d8176.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394381/6384eb19-70ac-0ec6-bd04-705219f0a8b1.png)

利便性のためにマウスオーバーするとマスクが解除されるようにしています。

# Javascript

```
/**************************************************
 * フィールド（フォーム設定のフィールドコード）に対し、下記対応を実施
 * 　閲覧時、* でマスクする
 * 　マウスオーバー時、マスクを解除する
**************************************************/
(function() {
    "use strict";

    // 閲覧時、 フィールド のマスク処理
    kintone.events.on([
        'app.record.detail.show',
    ], function() {

        var targetElement = kintone.app.record.getFieldElement('フォーム設定のフィールドコード');
        // テキストの取得
        var kintone_password = targetElement.innerText;
        // * でマスクする
        targetElement.innerText = maskPassword(targetElement);

        targetElement.addEventListener('mouseover', function(e){
            // マスクを解除する
            e.target.innerText = kintone_password;
        });

        targetElement.addEventListener('mouseout', function(e){
            // * でマスクする
            e.target.innerText = maskPassword(e.target);
        });
    });

    function maskPassword(targetElement){
        var mask = targetElement.innerText.replace(/./g, '*');
        return mask;
    }
})();
```
React 19 の 新機能 useActionState を触ってみた

# はじめに
この記事では、React 19 で新たに追加された `useActionState` という hook で簡単な実装を行い、その動作を確認してみます。

https://react.dev/reference/react/useActionState

# 開発環境
開発環境は以下の通りです。

- Windows 11
- VSCode
- JavaScript
- React 19.0.0-rc-cc1ec60d0d-20240607
- Vite 5.2.0
- Node.js 20.14.0
- npm 10.8.1

また、React 19 RC のインストール方法については、以下の記事に記載しています。

https://qiita.com/Yasushi-Mo/items/027503cbe4b299d99bed

# `useActionState` の実装
```
useActionState(action, initialState, permalink?)
```

`useActionState` では、アクションの実行、実行ステートの管理、アクションの結果の取得ができます。

```App.jsx
import { useActionState } from "react";

function App() {
  const [likeCount, formAction, isPending] = useActionState(async () => {
    const response = await fetch("https://example.com/like", {
      method: "POST",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ likeCount }),
    });
    const jsonResponse = await response.json();
    return jsonResponse.likeCount;
  }, 0);
  console.log("🚀 ~ App ~ \nisPending:", isPending, "\nlikeCount:", likeCount);

  return (
    <form action={formAction}>
      <strong>Like: {likeCount}</strong>
      <hr />
      <button type="submit" disabled={isPending}>
        Like
      </button>
    </form>
  );
}

export default App;

```

# 動作確認
Like ボタンをクリックすると、`formAction` 内の処理が実行されます。処理開始後、`isPending` が `true` になります。処理が完了すると、`isPending` は `false` になり、アクションの結果として、`likeCount` の値が更新されます。

![Vite-React-Google-Chrome-2024-06-13-09-44-38.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/79914243-436d-1aa7-e99f-afb3ee3c12a6.gif)

# 参考
- [React 19 RC](https://react.dev/blog/2024/04/25/react-19)
- [useActionState](https://react.dev/reference/react/useActionState)
- [\<form>とアクション](https://zenn.dev/uhyo/books/react-19-new/viewer/form-action)

# 関連記事
https://qiita.com/Yasushi-Mo/items/027503cbe4b299d99bed

https://qiita.com/Yasushi-Mo/items/3bebc244a97534c96382

https://qiita.com/Yasushi-Mo/items/abaddd44b92ba007e0c7
【Jaspersoft Studio】改ページがされない原因と解決方法

# 使用環境

- Windows 11 Pro (64bit)
- Jaspersoft® Studio 6.17.0

# 問題
Breakを追加しても改ページされず、すべてが1ページに繋がって出力される(ページサイズは固定なのに)。

# 試したこと
BreakのPrint When Expressionにtrueは設定したが、それでもダメ。改ページ専用のGroupを作成し、そこにBreakを入れても、状況は変わらない。

# 原因
ReportのPropertiesにある「Ignore Pagination」にチェックが入っていた。

# 解決方法
ReportのPropertiesにある「Ignore Pagination」のチェックを外す。
→Breakを消しても、指定したページサイズで1ページごとに出力される。

![ignore_pagenation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293169/cca28ba6-750b-e249-ed76-41b6dc028c99.png)
おすすめ全探索問題【AtCoder】

## はじめに

AtCoderに取り組む際、どの問題を解けば良いのか迷うことがあります。特に全探索に挑戦したい方に向けて、ネットで見つけた全探索問題を自分なりに収集し、この記事で整理しました。全探索を強化したい方の参考になれば幸いです。

## 履歴

2024/06/12 **新規作成**

## 問題

### シンプルな全探索

- [AtCoder Beginner Contest 144 B - 81](https://atcoder.jp/contests/abc144/tasks/abc144_b)
- [AtCoder Beginner Contest 150 B - Count ABC](https://atcoder.jp/contests/abc150/tasks/abc150_b)
- [AtCoder Beginner Contest 122 B - ATCoder](https://atcoder.jp/contests/abc122/tasks/abc122_b)
- [AtCoder Beginner Contest 136 B - Uneven Numbers](https://atcoder.jp/contests/abc136/tasks/abc136_b)
- [AtCoder Beginner Contest 106 B - 105](https://atcoder.jp/contests/abc106/tasks/abc106_b)
- [AtCoder Beginner Contest 120 B - K-th Common Divisors](https://atcoder.jp/contests/abc120/tasks/abc120_b)
- [AtCoder Beginner Contest 155 B - Papers, Please](https://atcoder.jp/contests/abc155/tasks/abc155_b)
- [AtCoder Beginner Contest 154 B - I miss you...](https://atcoder.jp/contests/abc154/tasks/abc154_b)

### 探索数を減らす全探索

- [AtCoder Beginner Contest 057 C - Digits in Multiplication](https://atcoder.jp/contests/abc057/tasks/abc057_c)
- [AtCoder Beginner Contest 095 C - Half and Half](https://atcoder.jp/contests/abc095/tasks/arc096_a)
- [三井住友信託銀行プログラミングコンテスト2019 D - Lucky PIN](https://atcoder.jp/contests/sumitrust2019/tasks/sumitb2019_d)

### bit全探索

- [AtCoder Beginner Contest 128 C - Switches](https://atcoder.jp/contests/abc128/tasks/abc128_c)
- [AtCoder Beginner Contest 147 C - HonestOrUnkind2](https://atcoder.jp/contests/abc147/tasks/abc147_c)


### 順列全探索

- [AtCoder Beginner Contest 145 C - Average Length](https://atcoder.jp/contests/abc145/tasks/abc145_c)
- [AtCoder Beginner Contest 150 C - Count Order](https://atcoder.jp/contests/abc150/tasks/abc150_c)
- [AtCoder Beginner Contest 054 C - One-stroke Path](https://atcoder.jp/contests/abc054/tasks/abc054_c)

#### 難しい

- [AtCoder Beginner Contest 332 D - Swapping Puzzle ](https://atcoder.jp/contests/abc332/tasks/abc332_d)

## 参考記事

- [レッドコーダーが教える、競プロ・AtCoder上達のガイドライン【初級編：競プロを始めよう】](https://qiita.com/e869120/items/f1c6f98364d1443148b3)
- [たのしい探索アルゴリズムの世界【前編：全探索、bit全探索から半分全列挙まで】](https://qiita.com/e869120/items/25cb52ba47be0fd418d6)
- [たのしい探索アルゴリズムの世界【後編：探索手法で実社会の様々な問題を斬る！】](https://qiita.com/e869120/items/72cc1370cbc0da1be9ef)
【Figma Plugins】テキストノードを生成する

## はじめに
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/85396574-18ce-04ac-a9b1-58158f27aa35.png)

FigmaのPluginを開発する際、テキストノードを生成したいなと思ったことはありますか？
そんな時に使うのが、「**createText()**」です。

この記事では、「**createText()**」について、解説しようと思います。

## テキストノードを生成する
テキストノードを生成するのに最低限必要なコードは、以下のコードです!

```createText.ts
const createText = async() => {
    /* テキストノードを生成する */
    const text = figma.createText();
    /* フォントをロードする（非同期処理） */
    await figma.loadFontAsync(text.fontName as FontName);
    /* テキストを決める */
    text.characters = 'Hello, world!';
}
```

1. `figma.createText()`を使って、オブジェクトを生成します
1. `figma.loadFontAsync()`でフォントをロードします
    - `figma.loadFontAsync`は、Promiseオブジェクトなので、非同期処理をしています
1. `text.characters`でテキストを決めています

すると、

座標が `x:0, y:0` の位置に `family: "Inter", style: "Regular"` で `rgb(0, 0, 0)`のテキストが生成されます。

## 生成するテキストをカスタマイズする
### ○ テキストの色を決める
テキストの色を決めるのは、`.fills` に値を渡すことで色を決めることができます。

```ts
/* rgbのテキスト */
text.fills = [{type: 'SOLID', color: {r: 0, g: 0, b: 0}}];
/* rgbaのテキスト co*/
text.fills = [figma.util.solidPaint('#000000AA')];
```

### ○ テキストのサイズを決める
テキストのサイズを決めるのは、`.fontSize` に値を渡すことで色を決めることができます。

```ts
/* 20pxのテキスト */
text.fontSize = 20;
```

### ○ リンクテキストを生成する

リンクテキストを生成するには、`.hyperlink` に値を渡すことでリンクにすることができます。

```ts
/* https://qiita.com/ へのリンクテキスト */
text.hyperlink = {type: "URL", value: 'https://qiita.com/'}
```

### ○ テキストのAlignを決める
テキストのAlignを決めるには、`.textAlignHorizontal`に値を渡すことで、決めることができます。

```ts
/* CENTER | JUSTIFIED | LEFT | RIGHT を受け取る */
text.textAlignHorizontal = 'CENTER'
```

### ○ テキストを追加する
テキストを追加するには、`insertCharacters()`に値を渡すことで、テキストを追加することができます。

```ts
/* テキストの最後に world を追加する */
text.insertCharacters(text.characters.length, 'world', 'AFTER')
```


## まとめ
この記事では、「**テキストノードの生成の仕方**」について解説しました。

---

最後まで読んでくださってありがとうございます！

普段はデザインやフロントエンドを中心にQiitaで記事を投稿しているので、ぜひQiitaのフォローとX(Twitter)のフォローをお願いします。

https://twitter.com/degudegu2510
ObsidianとELYZAの言語モデルを使って手軽に実現するローカルLLM活用

## はじめに
ChatGPTをはじめとした生成AIの活用はすでに当たり前になっている状況です。しかし、クラウドベースの利用にはデータプライバシーの懸念やコストが伴うため、ローカル環境で同様のことが行えるメリットはそれなりに高いのではないかと思います。この記事ではELYZAが公開しているモデルをローカル環境にセットアップし、それをObsidian経由で利用できるようにするまでの方法を紹介します。

## 環境
- Model: MacBook Pro 14-inch, Nov 2023
- Chip: Apple M3
- Memory: 24 GB
- OS: macOS 14.5

## LLMのセットアップ
### ollamaのインストール
ollamaは[こちら](https://ollama.com/download)からダウンロードし、`ollama.app` を実行します。ガイド通りにコマンドラインもインストールします。

### ELYZAモデルの追加
まずはELYZAのモデルを[こちら](https://huggingface.co/mmnga/ELYZA-japanese-Llama-2-7b-instruct-gguf/tree/main)からダウンロードします。今回は「ELYZA-japanese-Llama-2-7b-instruct-q4_K_M.gguf」をダウンロードしています。量子化具合による生成文章の違いについては[こちら](https://qiita.com/keisuke-okb/items/b8092ed946bcf3864295)が参考になるかと思います。次に下記のようにModelfileを作成します。FROM部分はダウンロードしたGGUF形式のファイルパスを指定します。

```
FROM ~/Downloads/ELYZA-japanese-Llama-2-7b-instruct-q4_K_M.gguf
TEMPLATE """
 
{{ .System }}


{{ .Prompt }} 

"""
PARAMETER stop "
"
PARAMETER stop "
"
PARAMETER stop "
"
PARAMETER stop "
"
```
Modelfileを作成したら、`ollama create` を実行します。
```
ollama create elyza:7b-instruct -f Modelfile
```
コマンドの実行結果としてsuccessと出れば成功です。`ollama list` で追加したモデルを確認することができます。

```
ollama list
NAME                   	ID          	SIZE  	MODIFIED	
elyza:7b-instruct      	2c15e90b556e	4.1 GB	3 weeks ago	
```
この状態になれば、`ollama run elyza:7b-instruct` で会話を試すことができるようになっています。

```
ollama run elyza:7b-instruct
>>> こんにちは、初めまして！
 こんにちは。
私はELYZAによって訓練されたAIです。
ユーザーからの様々な質問や要望にお答えすることを目的としています。お話いかがでしょうか？

>>> Send a message (/? for help)
```

続いて、Obsidianの方をセットアップします。

## Obsidianのセットアップ

### プラグインのインストール
まずは「[Copilot](https://github.com/logancyang/obsidian-copilot)」というCommunity pluginをまずはインストールします。

### プラグインの設定
次にプラグインの設定画面に下記のように設定値変更を行います。

- Default Model: OLLAMA (LOCAL)
- Ollama model: elyza:7b-instruct

## サーバを起動する

ObsidianのCopilotプラグインの設定画面に記載があるように、以下のコマンドを実行してサーバーを起動します。

```
OLLAMA_ORIGINS=app://obsidian.md* ollama serve
```

## チャットしてみる

サーバーを起動したら、Obsidianに戻ってCopilotのチャット画面を開きます。Ribbonにある吹き出しアイコンを選択するか、コマンドパレットで「Copilot: Toggle Copilot Chat Window」と入力するとチャット画面が開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118448/bfcdb17d-647a-03a0-7665-9a8310a6fac5.png)

Model Selectionで`OLLAMA (LOCAL)`が選択されていることを確認できたら、あとは何か話しかけると返答があることを確認できると思います。こんなふうに。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118448/44050863-a583-1d1c-c512-6ef2ab0de331.png)

一応、[ELYZA-tasks-100](https://huggingface.co/datasets/elyza/ELYZA-tasks-100)のデータセットからいくつかピックアップして評価してみたところ、主観ですが応答速度もおおむね十分ですし、回答も違和感ない結果になっていることが確認できました。

Obsidianと組み合わせることで、冒頭にも書いたデータプライバシーやコストを気にすることなく個人のノート作成に生成AIを活用できたり、ノートの内容をベースにチャットできたり、さらにはまだBetaですがVault全体をベースにしてチャットできるようにもなります。

## おわりに

環境によっては満足のいく結果にならないかもしれませんが、満足いく結果になる場合のメリットは大きいかと思います。ローカルLLM + Obsidianとの組み合わせによって、Obsidianで構築したSecond Brainがパワーアップする？！ことも期待できます。Apple Intelligenceの到来でどうなるかわかりませんが、興味ある方は試してみてください。公開されているモデルも色々あるので差し替えて試すのも面白いかと思います。

ちなみに、これは自分のとある貧相なノートの内容とチャットしたところです。以上。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118448/77504de6-02f8-faff-5925-eb65745b70db.png)
私はC++入門書が嫌い

こんにちは。tomcppfairyです。
今回は、日本語C++入門書に対する不満を挙げてみました。
**私自身もC++初心者な部分があるため、間違っている部分が有ればぜひおしえてください**

# 日本語C++入門書の不満な点
- ほとんど使わない機能を無駄に説明している

「プログラミングをできるだけ簡単にしたい」or「早くしたい」という人ならこれでいいかもしれませんが、それ以外では入門書の内容をそのまま受け止めるのはやめたほうがいいかと思います。
では、不満の詳細を述べていきます。

# 不満その一・ほとんど使わない機能を無駄に説明している
なぜ、ほとんどつかわない機能に大きく説明を割くのか、理解不能です。
まず、すぐに挙げられるのは下記のとおりです。
- Cスタイルの配列
- 生のポインタ
- new delete
- 生の列挙体
- typedef

一つずつ説明していきます。

## Cスタイルの配列
なぜこれを使うのか理解不能です。関数において、Cスタイルの配列を引数として渡した場合、先頭要素を指すポインタ型にキャストされます。つまり、要素数を別に指定する必要があり、めんどくさいです。また、固定長配列のため、使いにくいです。どうしても固定長配列を使いたいなら、`std::array`を使いましょう。そうでなければ`std::vector`などを使うといいと思います。

## 生のポインタ
理解できないことはありませんが、あまり使用したくないです。昨今のC++にはスマートポインタというものがあり、これを使用すればメモリのもろもろの問題を比較的気にせずともいいようになります。生のポインタは時代遅れです。

## new delete
newすれば必ずdeleteしなければならない。それを解決するためのものがスマートポインタです。new deleteも時代遅れです。

## 生の列挙体
列挙体自体は問題ありません。しかし、`enum {}`では不都合です。デフォルトでは、メンバには単純な数字が与えられるため、バグが生じる可能性が高いからです。`enum class {}`を使いましょう。これなら安心です。

## typedef
usingがあるのに、なんでtypedefを使うのでしょうか？　usingは関数ポインタなどを書く際非常にtypedefと比べて可読性が高くなります。また、テンプレートが使えます。typedefはテンプレート使えません。どう考えてもusingのほうが優秀ですね。
```c++:typedefの場合
template <typename T>
typedef std::vector<T> vec; //error!
```
```c++:usingの場合
template <typename T>
using vec = std::vector<T>; //OK!
```

# 不満その二・C++の理念を無視している
- `using namespace std;`を推奨している
- `bits/stdc++.h`をincludeすることを推奨している（場合による）

## using namespace stdを推奨している
言うまでもなく、論外ですね。名前汚染もいいとこです。せっかく標準でstd名前空間にふくんでいるのに、それを取り外す意味がありません。Pythonの`from modulename import *`くらいひどいです。
まず、可読性が低くなります。標準ライブラリの名前はシンプルなものが多いため、stdを外すと、標準ライブラリ関数なのか、自作関数なのかぱっと見でわかりません。std::printなどはいい例でしょう。
次に、先程も言ったように名前汚染がひどいです。標準ライブラリの名前はシンプルなものが多いため、長いプログラムを書くと、どこかで名前に引っかかります。それを解決するのがstdです。stdを省略するとその利点が失われます。

## bits/stdc++.hを推奨している
bits/stdc++.hは、プログラムがちょっと短くなる以外の利点がないです。
これについて少し調べたのですが、そもそも使い方を間違えているという記事を見つけました。これは私も知らなかったので掲載していきます。
https://qiita.com/hakatashi/items/f9d9abf05a002b5c4dc5

# 結論
どうだったでしょうか？　間違ったところが有ればおしえてくれたら助かります。