OmniAICreator/Qiita-1.07M huggingface dataset:
Kerasでニューラルネットワークモデル

ニューラルネットワークには様々なライブラリがリリースされており、これを使うと、大規模なニューラルネットワークが比較的短いコードで実装でき、さらに高速に動かすことができる。ここではKerasというライブラリを使っていく。

## 2層フィードフォワードニューラルネット
まずは3分類問題を解く2層フィードフォワードニューラルネットワークを作り動かす。

```python
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from scipy.optimize import minimize
import time

import keras.optimizers
from keras.models import Sequential
from keras.layers import Dense, Activation

outfile = np.load('class_data.npz')
X_train = outfile['X_train']
T_train = outfile['T_train']
X_test = outfile['X_test']
T_test = outfile['T_test']
X_range0 = outfile['X_range0']
X_range1 = outfile['X_range1']

def show_data(x, t):
    wk, n = t.shape
    c = [[0, 0, 0], [.5, .5, .5], [1, 1, 1]]
    for i in range(n):
        plt.plot(x[t[:, i] == 1, 0], x[t[:, i] == 1, 1], linestyle = 'none', marker='o', markeredgecolor='black', color=c[i], alpha=0.8)
    plt.grid(True)

# 乱数の初期化
np.random.seed(1)

# Sequentialモデルの作成
model = Sequential()
model.add(Dense(2, input_dim=2, activation='sigmoid', kernel_initializer='uniform'))
model.add(Dense(3, activation='softmax', kernel_initializer='uniform'))
sgd = keras.optimizers.SGD(learning_rate=0.5, momentum=0.0, decay=0.0, nesterov=False)
model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])

# 学習
startTime = time.time()
history = model.fit(X_train, T_train, epochs=1000, batch_size=100, verbose=0, validation_data=(X_test, T_test))

# モデル評価
score = model.evaluate(X_test, T_test, verbose=0)
print('cross entropy {0:3.2f}, accuracy {1:3.2f}'.format(score[0], score[1]))
calculation_time = time.time() - startTime
print("Calculation time:{0:.3f} sec".format(calculation_time))

plt.figure(1, figsize=(12, 3))
plt.subplots_adjust(wspace=0.5)

# 学習曲線表示
plt.subplot(1, 3, 1)
plt.plot(history.history['loss'], 'black', label='training')
plt.plot(history.history['val_loss'], 'cornflowerblue', label='test')
plt.legend()

# 精度表示
plt.subplot(1, 3, 2)
plt.plot(history.history['accuracy'], 'black', label='training')
plt.plot(history.history['val_accuracy'], 'cornflowerblue', label='test')
plt.legend()

# 境界線表示
plt.subplot(1, 3, 3)
show_data(X_test, T_test)
xn = 60
x0 = np.linspace(X_range0[0], X_range0[1], xn)
x1 = np.linspace(X_range1[0], X_range1[1], xn)
xx0, xx1 = np.meshgrid(x0, x1)
x = np.c_[np.reshape(xx0, xn * xn), np.reshape(xx1, xn * xn)]
y = model.predict(x)
K = 3

for ic in range(K):
    f = y[:, ic]
    f = f.reshape(xn, xn)
    f = f.T
    cont = plt.contour(xx0, xx1, f, levels=[0.5, 0.9], colors=['cornflowerblue', 'black'])
    cont.clabel(fmt='%1.1f', fontsize=9)
    plt.xlim(X_range0)
    plt.ylim(X_range1)

plt.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3850581/35d437f6-0fa3-8735-bd9d-a788af07c4c6.png)

画像は左から交差エントロピー誤差と学習ステップ数、重みと学習ステップ数、データ分布と決定境界線の図になっている。
【エラー解決ログ】Next.jsでuseStateが使えない

初学者のため、何か間違いがございましたらご指摘ください。

## 直面したエラー
```
  × You're importing a component that needs useState. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.
  │ Learn more: https://nextjs.org/docs/getting-started/react-essentials
```

## 実際のコード

```tsx:page.tsx
import Link from "next/link";
import { useState } from "react";

export default function CreatePage() {
  const [text, setText] = useState("");
  return (
    <div>
      <p>入力ページ</p>
      <p>フォーム</p>
      <form>
        <input
          type="text"
          id="text"
          name="text"
          value={text}
          onChange={(e) => setText(e.target.value)}
        />
        <button type="submit">Submit</button>
      </form>
      <Link href="/">ホームページへ</Link>
    </div>
  );
}
```

## 解決策

一行目に`"use client";`を追記する。

## エラーになっていた原因

page.tsxはデフォルトではサーバーコンポーネントだが、useStateやuseEffectなどのフックはクライアントコンポーネントでないと利用できない。
そのため、`"use client";`を追記することで、このコンポーネントをクライアントサイドでレンダリングするということを指定する必要があった。
Array.fromAsync()とPromise.all()の違い【JavaScript】

ようわからんかったのでメモ
# TL;DR

- Array.fromAsync()は順次実行
- Promise.all()は同時実行

```javascript
const sleep = delay => new Promise(resolve => setTimeout(resolve, delay))

console.time()
await Array.fromAsync([200, 100, 300], sleep)
console.timeEnd()
// elapsed: 600ms

console.time()
await Promise.all([200, 100, 300].map(sleep))
console.timeEnd()
// elapsed: 300ms
```

https://qiita.com/mellbrother/items/715ff5dce5845381eeee#comment-202a45c5d467a5dd67dc 

cc @juner 

## 戻り値

どちらも解決した値が入ってくる。HTTPリクエストを投げたいときにDoS攻撃したくないなら、Array.fromAsync()はあり！

```javascript
const sleep = delay => new Promise(resolve => setTimeout(() => resolve(delay), delay))

console.time()
console.log(await Array.fromAsync([200, 100, 300], sleep))
console.timeEnd()
// elapsed: 600ms

console.time()
console.log(await Promise.all([200, 100, 300].map(sleep)))
console.timeEnd()
// elapsed: 300ms
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/5808eaf9-445b-d372-4448-3de8628e4e5f.png)



こんな感じでDoS攻撃を防げます
```js
const responses = await Array.fromAsync(Array(30), () => fetch('https://httpbin.org/uuid'))
console.log(responses)
```
Azure Pipelineで2つ連結させて動かす

Azure Pipelineを使う機会があったのでメモしておきます。
`Pipeline1`、`Pipeline2`があるとして`Pipeline1`の完了をトリガーにして`Pipeline2`を動かすように構成を行いました。

こちらの公式の記事を参考にしました。
→[パイプラインを 1 つずつトリガーする](https://learn.microsoft.com/ja-jp/azure/devops/pipelines/process/pipeline-triggers?view=azure-devops)


`Pipeline2`のyamlは以下の様に記載しました。
`resources`にそれぞれ設定をしていきます。
* `pipeline`: パイプライン名
* `source` : トリガーとなるパイプライン名（フォルダ名から指定しないといけないので注意！）
* `trigger` : パイプライン完了トリガーを有効にする

```yaml
trigger: none

resources:
    pipelines:
        - pipeline: Pipeline2
          source: deploy\prd\Pipeline1
          trigger: true
pool:
    vmImage: ubuntu-latest

jobs:
    - job: e2e
    - ......
    - ......
```

`branches`を指定して`release`フォルダにマージされたときのみ動作させることなども可能です。

成功すると、`Automatically triggerd by ...`のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/b6676a12-e91a-1330-d567-65c19487e6bf.png)

私の場合はこれで動作させることができました。


ただし、1点問題が発生しました。`variables`に環境変数を設定していたのですが、`Pipeline1`の環境変数がそのまま `Pipeline2`に引き継がれる形となってしまいました。ですのでいったんの対策として、yamlの中に直接記入することで上書きをしてくれました。

```yaml
variables: 
    target: './tests/basic/'
    tenantId: 'e2ebasic'
```
OpenAI o1 APIの効果的な使用方法：複雑なタスクに対する推論力を最大化する

![apidog-ai.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877124/4770aba1-3213-4b1f-b4de-e2c8d493a5b6.png)

近年、人工知能（AI）の進化は目覚ましく、特にOpenAIのAPIを活用したAIモデルは、世界中でさまざまな分野に影響を与えています。OpenAIは、特定のタスクに応じてモデルを指定することが可能であり、その選択はユーザーにとって非常に重要な意思決定となります。本稿では、OpenAI APIのモデル指定に関する課題と、その選択基準について詳しく考察し、ITやAI分野での応用可能性について論じます。

OpenAIの新しいAPIモデルであるo1は、推論能力に優れ、さまざまなタスクに対して効果的な解決策を提供することで注目を集めています。このAPIの特性を最大限に活用するには、適切な使用方法を理解することが重要です。本稿では、OpenAI o1 APIの使用方法について、詳細にわたる考察とともに、使用上のポイントを客観的に分析していきます。

## 1. OpenAI o1 APIの基本的な使い方
まず、OpenAI o1 APIの使用方法は、従来のGPT-3やGPT-4 APIと大きくは変わりませんが、o1の強化された推論能力を効果的に活用するためにいくつかの注意点があります。APIの利用は基本的に以下の手順で行われます：

### APIキーの取得
OpenAIの公式ウェブサイトからアカウントを作成し、APIキーを取得します。これはすべてのAPIリクエストに必要な認証情報であり、適切な権限と使用制限を伴います。
### ライブラリのインストール
OpenAIのAPIを簡単に使用できるように、Python用のOpenAIライブラリをインストールします。このライブラリは、リクエストの送信、レスポンスの処理、およびエラーの処理を効率化するツールです。
### APIリクエストの設定
APIを呼び出すためには、適切なエンドポイントを指定し、リクエストの形式を設定します。これには、モデル（この場合は「o1」）、プロンプト（入力データ）、およびその他のオプション（例：温度、トークン数の制限など）の指定が含まれます。
### レスポンスの処理
APIから返されるレスポンスは、通常JSON形式で提供されます。ここには、モデルが生成したテキストや推論結果が含まれています。このレスポンスを正確に解析し、必要に応じてデータを保存または表示します。

## 2. o1 APIの特徴と他モデルとの違い
OpenAI o1 APIは、特に強化学習を活用した次世代のAIモデルです。GPT-3やGPT-4に比べ、o1は以下のような特徴を持っています：

### 強化された推論能力
o1は、特に複雑なタスクや多段階の問題解決において、高い推論能力を発揮します。例えば、プログラムのバグ修正や複雑な数学的問題の解決など、段階的な分析と判断が必要なタスクでその真価を発揮します。
### モデルの柔軟性
o1は、自然言語処理だけでなく、コード生成やデータ解析など、多様なタスクに対応できる汎用性を持っています。これにより、さまざまな業界や用途での応用が期待されています。
### コストとリソースのバランス
高度な推論能力を提供するため、o1の利用には他モデルと比較して高いコストがかかります。特に、大規模なプロジェクトや多くのリクエストを送信する際には、コスト管理が重要な課題となります。

## 3. o1 APIの効果的な活用方法
o1 APIを最大限に活用するためには、以下のポイントに留意する必要があります。

### タスクに応じた適切なモデル選択
o1は複雑なタスクに強みを発揮しますが、すべてのタスクに最適というわけではありません。単純なテキスト生成や簡単な質問応答には、GPT-3やGPT-4がコストパフォーマンスの観点で優れている場合があります。そのため、タスクの内容に応じてモデルを適切に選択することが重要です。

### パフォーマンスチューニング
o1 APIを使用する際には、リクエストのパラメータを調整することで、応答時間や精度を最適化できます。例えば、トークン数の制限や温度設定を調整することで、より精度の高い応答が得られる場合があります。また、不要なトークンの生成を抑えることで、コスト削減も期待できます。

### エラーハンドリングとデバッグ
API利用中に発生するエラーを適切に処理することも重要です。APIは、時折、制限に達することや接続エラーを引き起こす可能性があります。その際には、適切なエラーハンドリングを行い、リクエストの再送やログの解析を通じて原因を特定します。

## 4. 今後の展望と注意点
OpenAIは、今後もAPIの機能強化と新モデルの開発を進める予定です。o1 APIのさらなる発展は、特に以下の点で期待されています：

### 自動化のさらなる促進
o1の高度な推論能力は、これまで人間が行っていた複雑な判断や分析を自動化する可能性を秘めています。特に、プログラミングやデータ解析の分野では、より多くの業務がAIに任される未来が予想されます。

### 新しい機能の追加
現在のo1 APIには、ウェブブラウジングやファイル処理機能が含まれていませんが、将来的にはこれらの機能が追加され、より多様なタスクに対応できるようになるでしょう。


## 結論
OpenAI o1 APIは、特に複雑な推論や高度な問題解決を必要とするタスクにおいて強力なツールです。その使用方法を正しく理解し、適切な設定とモデル選択を行うことで、さまざまなプロジェクトにおいて効果的に活用できます。今後も進化を続けるこのAPIの可能性に注目しながら、効率的な利用を目指すことが重要です。

最後まで見ていただきありがとうございました！
では、また次の記事で～！
Ranorex の便利機能 - 待機アクション

## はじめに
テスト対象アプリに対してUIテストを実施する場合、ある特定の操作をおこなったあと、次の画面に遷移するまで待機し、画面が表示されたタイミングで次の操作をおこなう必要があります。

このような場合、UIテスト自動化ツール の[Ranorex](https://ranorex.techmatrix.jp)（※）では、次の画面遷移を待機するアクションが用意されています。
※Ranorex は、デスクトップ/Web/モバイルアプリの自動化に対応しています。
　テスト対象アプリのUI操作を記録し、テストの作成/実行を可能とします。


## アクションの種類
Ranorex の待機アクションとして、以下の3種類があります。
* Delayアクション：設定した時間を待機するアクション
* Wait Forアクション：任意のオブジェクトの存在・消失状態を待機するアクション
* Invoke Action – WaitForDocumentLoaded() アクション：Web ページのロードを待機するアクション

## 使用例① Delayアクション
テスト実行時に特定の操作のタイミングで一定時間待機したい場合には、Delayアクションを使用します。
使用例②でご紹介するWait Forアクションでは、オブジェクトの存在・消失状態などで次のアクションに移るため、その時によって待機時間が異なりますが、Delayアクションでは、設定した時間分必ず待機したうえで次のアクションに移ります。

以下の例では、Delayアクションにて10秒間待機したあと、ログインボタンを押下します。
![Delayアクション.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826211/1fd092ed-c6e0-a46b-e5f1-ec5ac5f6a3b5.png)

## 使用例② Wait Forアクション
Ranorex のWait Forアクションには、以下の種類が用意されています。
* Exists：対象のオブジェクトが存在するまで待機します
* NotExists：対象のオブジェクトが消失するまで待機します
* AttributeEqual：属性が特定の値と等しくなるまで待機します
* AttributeRegEx：正規表現を利用し、特定の属性の照合値が一致するまで待機します

たとえば、ある一定の処理がおこなわれたあとに有効化するボタンが存在する場合、有効化される前にボタンが押下されてしまうケースがあります。この場合、実際に特定のボタンは押下されておらず、テストが失敗してしまいます。
上記の問題に対しては、Wait For - AttributeEquel アクションにて、特定のボタンが有効化されることを待機することで解決できます。

以下の例では、Wait For - AttributeEquel アクションにて、ログインボタンのEnabled属性がtrueになるまで待機します。
※Enabled属性は、HTML要素を有効化する属性です。Enabled属性がtrueの場合、対象の要素は有効化された状態となります。
![WaitFor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826211/264b633d-1a6b-dd6d-2620-08c9a32e2efe.png)
これにより、ログインボタンが有効化されるまで待機し、対象のボタンが有効化されたあと、ログインボタンを押下します。

## 使用例③ Invoke Aciton - WaitForDocumentLoaded()
Webアプリケーションをテストする場合、画面のロードに時間がかかってしまうと、対象のアプリケーション画面が完全に表示されていない状態で次の操作が実施されてしまうケースがあります。この場合、次の操作は期待通りに実施されず、テストが失敗してしまいます。
上記の問題に対しては、Invoke Action - WaitForDocumentLoaded()アクションにて、画面のロードを待機することで解決できます。

Invoke Action - WaitForDocumentLoaded()アクションのRepository itemには、対象のWebページのルートエレメント（DOM）を指定します。
![InvokeAction.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826211/7c8ac521-438e-ef74-6c22-adf1c0d7186d.png)

これにより、指定したWebページの画面のロードを待機し、画面のロードが完了したあとに次の操作に移ります。

## まとめ
今回は、Ranorex で用意されている待機アクションについて紹介しました。
テスト対象のアプリケーションを自動化する場合、必要に応じて各操作のタイミングを調整するが必要ありますが、Ranorex では様々な待機アクションが用意されているため、安定性の高いテストを作成することができます。

Ranorex をご利用いただく場合には、必要に応じて待機アクションをご利用ください。
ロリポップのライトプランを利用したWordPressを構築

# はじめに
ロリポップのライトプランを利用してWordPressを構築する方法を記します。

# 構築手順
### 手順1: ロリポップの契約と初期設定

1. **ロリポップの公式サイト**にアクセスし、ライトプランを申し込みます。
   - [ロリポップ公式サイト](https://lolipop.jp/)にアクセスしてアカウントを作成し、ライトプランを選択します。
   
2. **契約後の初期設定**:
   - サーバーの設定画面に移動し、管理画面から「ユーザー専用ページ」にログインします。

### 手順2: 独自ドメインの取得と設定（任意）

1. ロリポップを利用する場合、独自ドメインを利用したい場合は、ドメインを取得し設定します。ロリポップでもドメイン取得サービスを提供していますが、他のドメイン取得サービスを利用することも可能です。
2. 「サーバー管理・設定」メニューから「独自ドメイン設定」に移動し、取得したドメインを設定します。
※ロリポップのドメインを使う場合、後続の6.SSL対応は不要です。

### 手順3: MySQLデータベースの作成

1. **ロリポップのユーザー専用ページ**にログインします。
2. 「WEBツール」 > 「データベース」メニューに進みます。
3. 「データベース作成」ボタンをクリックし、新しいデータベースを作成します。
   - **データベース名**: 任意の名前を設定（例: `wordpress_db`）
   - **ユーザー名**: デフォルトのままか任意で設定
   - **パスワード**: セキュアなパスワードを設定
   - **データベースの種類**: `MySQL`
   - **文字コード**: `utf8mb4_general_ci`（推奨）

### 手順4: WordPressのインストール

1. **WordPress簡単インストールを使用する方法**:
   - 「WEBツール」 > 「WordPress簡単インストール」メニューを選択します。
   - WordPressをインストールしたいドメインを選択します。
   - 「サイトのタイトル」、管理者の「ユーザー名」「パスワード」「メールアドレス」を入力します。
   - 「データベース選択」で先ほど作成したデータベースを選択します。
   - 「インストール確認」ボタンをクリックして、設定を確認したら「インストール」ボタンを押します。

2. **手動でWordPressをインストールする方法**:
   - [WordPressの公式サイト](https://ja.wordpress.org/)からWordPressをダウンロードし、解凍します。
   - FTPクライアントソフト（FileZillaなど）を使用して、ロリポップサーバーに接続し、WordPressのファイルをサーバー上の`public_html`ディレクトリにアップロードします。
   - ブラウザでインストールしたドメイン（例: `http://yourdomain.com`）にアクセスし、インストールウィザードに従います。
   - データベース情報（データベース名、ユーザー名、パスワード、ホスト名）を入力し、インストールを進めます。

### 手順5: WordPressの初期設定

1. WordPressのインストールが完了したら、管理画面（ダッシュボード）にログインします。  
   URL例: `http://yourdomain.com/wp-admin/`
   
2. 必要なテーマやプラグインをインストールし、サイトのデザインと機能をカスタマイズします。

### 手順6: SSL化（HTTPS対応）の設定
※ロリポップのドメインを使う場合は不要。選択できない

1. ロリポップの管理画面で「セキュリティ」 > 「独自SSL証明書導入」に進みます。
2. 無料の「Let’s Encrypt」SSLを利用するか、有料のSSL証明書を購入して導入することで、サイトをHTTPS化します。
XAMPPを使用したWordPress環境構築

# はじめに
WordPressの開発環境構築目的でXAMPPを使用します。

# 構築ステップ
### ステップ1: XAMPPのインストール
1. [XAMPPの公式サイト](https://www.apachefriends.org/index.html)にアクセスし、Windows、macOS、またはLinux用の最新バージョンのXAMPPをダウンロードします。
2. ダウンロードしたインストーラを実行し、画面の指示に従ってインストールを完了します。
3. インストールが完了したら、XAMPPコントロールパネルを開き、`Apache`と`MySQL`のサービスを「Start」ボタンをクリックして起動します。

### ステップ2: WordPressのダウンロードとセットアップ
1. [WordPressの公式サイト](https://ja.wordpress.org/)にアクセスし、最新のWordPressパッケージをダウンロードします。
2. ダウンロードしたZIPファイルを解凍し、解凍した「wordpress」フォルダをXAMPPのインストールディレクトリ内の「htdocs」フォルダにコピーします。例えば、`C:\xampp\htdocs\wordpress`とします。
3. ブラウザを開き、`http://localhost/phpmyadmin/`にアクセスして、WordPress用の新しいデータベースを作成します。  
   - `phpMyAdmin`で、「データベース」タブをクリックし、新しいデータベース名（例: `wordpress_db`）を入力して、「作成」ボタンをクリックします。
   - 照合順序（collation）は`utf8mb4_general_ci`を選択
       - 理由
           - **UTF-8の拡張サポート**: `utf8mb4`はMySQLで拡張されたUTF-8キャラクターセットで、4バイト文字（絵文字など）をサポートしています。`utf8`は3バイト文字までしかサポートしていないため、`utf8mb4`の方がより多くの文字セットをカバーします。
           - **`general_ci`の利点**: `utf8mb4_general_ci`は一般的な用途に最適化された照合順序で、大文字小文字の区別をせず、ほとんどの言語のテキストに適しています。`utf8mb4_unicode_ci`よりもパフォーマンスが良いことが多いため、標準的な使用には`utf8mb4_general_ci`が推奨されます。
           - **WordPress推奨**: WordPressはデフォルトで`utf8mb4`を使用するようになっており、新しいインストールやデータベースを設定する場合も`utf8mb4`を推奨しています。

### ステップ3: WordPressのインストール
1. ブラウザで`http://localhost/wordpress/`にアクセスします。
2. インストール画面が表示されるので、言語を選択して「続ける」をクリックします。
3. 「データベース接続の詳細」を入力する画面が表示されるので、以下の情報を入力します：
   - データベース名: 作成したデータベース名（例: `wordpress_db`）
   - ユーザー名: `root`
   - パスワード: 空白のまま
   - データベースのホスト: `localhost`
   - テーブル接頭辞: 任意（`wp_`のままでもOK）
4. すべての情報を入力したら、「送信」をクリックし、次の画面で「インストールを実行」をクリックします。
5. サイトのタイトル、ユーザー名、パスワード(ローカル環境なのでなんでもよい)、メールアドレス(ローカル環境なのでなんでもよい)を入力し、「WordPressをインストール」をクリックします。

### ステップ4: WordPressのセットアップ完了
1. インストールが完了すると、WordPressのダッシュボードにログインできるようになります。ブラウザで`http://localhost/wordpress/wp-admin/`にアクセスし、先ほど設定したユーザー名とパスワードでログインします。
HomesteadでLaravelプロジェクトを作成したら403 forbiddenで詰まった話

## はじめに
自分がこの単純な原因に半日苦しめられたので、怒りと悲しみの備忘録です。
（もう同じ過ちは繰り返さぬ…）

## 結論
`homestead.yaml`の`sites:`のパス指定が間違っている可能性大！

### 正しい例
```yaml:homestead.yaml
sites:
    - map: laravelapp.test
      to: /home/vagrant/code/laravelapp/public
```
:::note info
index.phpが存在するpublicまでパスが書いてある
:::

### ダメな例
```yaml:homestead.yaml
sites:
    - map: laravelapp.test
      to: /home/vagrant/code/laravelapp # ←ここ！！
```
:::note alert
publicまで指定していない！
単純なパス指定ミス
:::

## 解説
いわゆる 許可されていない領域にアクセスしようとすることで発生するエラー です。

HTTPリクエストが飛んでくるとサーバーエンジンが指定されたパスに対象のページを取得しに参照しますが、そもそもプロジェクトフォルダ直下は権限外なため権限がありません（403 forbidden） となってしまうんですね。

publicフォルダ内には参照権限がありますので、しっかりと正しいパスでpublicまで届いていれば解消できるということになります。

皆様もくれぐれもお気を付けください…（2敗）

## 参考
https://blog.hubspot.jp/marketing/http-403-forbidden
Windows ターミナルで一時PATHを設定したPowerShellプロファイルを追加する

## 一時PATHを設定したPowerShellコンソールを利用したい
特定の開発環境やツールを利用する際に、一時的にコマンドPATHを設定したPowerShllコンソールを利用したいことがあります。

起動後に手動で入力したり、スクリプトファイルを実行すれば実現可能ですが、毎回それを行うのは面倒です。

さりとて、グローバルの環境変数を変更するとコマンドの競合などで思わぬ落とし穴にはまってしまうことがあります。

これらの問題を解決する方法として、本記事ではWidnows ターミナルに一時的なPATHを設定したPowerShellプロファイルを追加する方法について記載します。

### Windows ターミナルに新しいプロファイルを追加する

Windwos ターミナルの新しいプロファイルを追加を行います。ベースとなるプロファイルは`PowerShell` か `Windows PowerShell` を選択してください。

コマンドラインの項目にPATHを設定する起動オプションを追加します。既存のPowerShellのコマンドラインに続けて以下の文字列を追加します。

ダブルクオート内でダブルクオートを表現するためには `""` と二重にする必要があります。

```
 -noexit -Command "Set-Item ENV:PATH ""$ENV:PATH;追加するパス"""
 ```

上記のオプションを追加することで、PATHに一時PATHを追加してPowerShellを起動するプロファイルとなります。

これはPowerShellの `-Command` オプションでコマンドを実行することで実現しています。同様に、PATH以外の環境変数の設定など、他のPowerShellコマンドを実行することができます。

複数のPowerShellコマンドを実行したい場合はセミコロン `;` でつなげることで実現できます。

### あとがき
検索サイトや生成AIを使っても、そのものずばりの回答は得られなかったので、備忘録としてまとめました。
PythonでExcel XLS形式とXLSX形式を変換する

日常業務では、さまざまなニーズやソフトウェアの互換性に合わせて、異なるフォーマットのExcelファイルを処理したり変換したりする必要がよくあります。Excelファイルの一般的なフォーマットはXLS（Excel 97-2003）とXLSX（Excel 2007以上）の2つです。この記事では、Pythonを使ってXLS形式とXLSX形式を変換する方法を紹介します。

* [PythonでXLSXをXLSに変換する](#pythonでxlsxをxlsに変換する)
* [PythonでXLSをXLSXに変換する](#pythonでxlsをxlsxに変換する)


## Python ライブラリ - インストール
必要なPythonライブラリはSpire.XLS for Pythonです。このPythonライブラリは、Excelドキュメントの作成、読み込み、編集、変換など、プログラムによる操作を幅広くサポートします。
このリンクからパッケージをダウンロードしてローカルパスからインストールするか、以下のpipコマンドを使って直接インストールすることができます： 
`pip install Spire.XLS`


## XLS形式とXLSX形式の変換
**XLSX**フォーマットは、XMLベースの構造、豊富な機能サポート、セキュリティ機能により、最新のExcelファイルを扱うための一般的な選択肢となっています。一方、**XLS**フォーマットは、旧バージョンのExcelとの互換性や特定の機能の使用により、依然として特定のアプリケーションシナリオを持っています。

Pythonを使用して、これら2つのフォーマット間で柔軟な変換を行うには、以下の手順を参照してください：
1\.	**`Workbook`** オブジェクトを作成します。
2\.	**`LoadFromFile()`** メソッドを使用して、.xls または .xlsx ファイルをロードします。
3\.	**`SaveToFile(fileName, version)`** メソッドを使用して、ロードしたファイルを別の形式で保存します。


> :point_down: **コード例を以下に示す：**

## PythonでXLSXをXLSに変換する
```python
from spire.xls import *
from spire.xls.common import *
 
# XLSXファイルの読み込み
workbook = Workbook()
workbook.LoadFromFile("sample.xlsx")
 
# XLSXファイルをXLS形式で保存する
workbook.SaveToFile("XlsxToXls.xls", ExcelVersion.Version97to2003)
workbook.Dispose()
```

## PythonでXLSをXLSXに変換する
```python
from spire.xls import *
from spire.xls.common import *
 
# XLSファイルの読み込み
workbook = Workbook()
workbook.LoadFromFile("sample.xls")
 
# XLSファイルをXLSX形式で保存する
workbook.SaveToFile("Xls转Xlsx.xlsx", ExcelVersion.Version2016)
workbook.Dispose()
```
* * *
Spire.XLS for Pythonは、Excel（.xls/ .xlsx）ファイルをPDF、画像、HTML、その他多くのファイル形式に変換することもサポートしています。チュートリアルは以下をご覧ください：

https://www.e-iceblue.com/Tutorials/Python/Spire.XLS-for-Python/Program-Guide/Spire.XLS-for-Python-Program-Guide-Content.html
Best Self Defense Stun Gun For Women

https://www.youtube.com/watch?v=0cWTQvLiDCg&ab_channel=StunnerSafety
![logo.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3888818/4f0d58a8-1fcd-81a8-3e11-0a12e1246433.jpeg)
複数の自動テスト作成で流用できるコード

# はじめに

今まで自動テストを作成したことは無かったのですが、半年程前から業務で自動テストを作成するようになりました。その際に複数の自動テストで流用している汎用性の高いコードがありましたので、それらをまとめてみようと思いました。

# 1. リストから変数の名前を検索し、見つかった際にアクションする
```
steps.listTest()
        .statusIs(200)
        .getResponse()
        .as(new TypeRef<List<Response>>() {
        })
        .stream()
        .filter(test -> test.getName().equals(NAME))
        .findFirst()
        .ifPresent(test -> {
            testId = test.getId();
            steps.install(testId);
        });
```
###### 解説
Testのリストを取得し、そのリストから名前が「NAME」のものを検索する。見つかった場合は「testId」に「NAME」のIDを入れてそのテストをインストールする。

# 2. レスポンスを10分間確認し、変化があった際に条件分岐する
```
for (int i = 0; i <= 600; i++) {
    Thread.sleep(1000);
    var response = steps.get(id)
            .getResponse()
            .as(Response.class);
    if (response.getStatus().equals("UP")) {
        serviceName = response.name;
        break;
    }
}
if (serviceName.isEmpty()) {
    fail("The status does not become ");
}
```
###### 解説
10分間毎秒「response」のステータスを確認し、「UP」になったら「serviceName」に「response」の名前を代入する。「UP」にならなかった際はエラーメッセージを表示する。

# 3. 複数の条件が全てtrueだった際にアクションする
```
boolean logsExist = Objects.nonNull(logsResponse) &&
        Objects.nonNull(logsResponse.status) &&
        logsResponse.status != 0;
if (logsExist) {
    logs = logsResponse;
} else {
    fail("log does not exist");
}
```
###### 解説
「logsResponse」がnullではなく、ステータスがnullでも0でもない時に「logs」に「logsResponse」を代入する。条件に当てはまらなかった際はエラーメッセージを表示する。

# 最後に
今まで自動テストを作成したことが無かった私ですが、既存のテストコード確認やグーグル検索、AIに質問をすることで作成できるようになってきました。この記事にも書いていますが、一度作成したテストコードは他のテストにも流用できることが多いので、1つテストを作成できると2つ目以降はスムーズに作成できるようになりました。他の方がどのように自動テストを作成しているかはわかりませんが、もし参考になりましたら幸いです。
SpringBoot初学者の備忘録

# はじめに

こんにちは、Gakken LEAP のエンジニアの okamotoです。
普段の業務で使用しているSpring Bootについて、使ってはいるものの仕様や仕組みについて理解ができていない部分が多いと感じたため、基本から学んでみました。
今回はその一歩目として学んだものを備忘録として本記事にのこします。

# Spring Bootの登場

Springフレームワークの中の一つにSpring MVCというMVCモデルに基づいたフレームワークがあり、
それだけでは他のフレームワークを色々組み合わせなければならず、使いづらい部分があった。
（Spring Rooという各種コードの自動生成機能ライブラリで補完することである程度は楽になっていた）

そこで登場したSpring BootはSpring MVCの完成系とされており、上記の二つ＋αの組み合わせを完全に上回った利便性がある。

# Spring Bootの利便性とは

とにかく楽である。
どう楽なのかというと、
> 他のフレームワークを色々組み合わせなければならず

↑の部分を設定ファイルにスターターライブラリをちょっと書くだけで全部自動にやってくれるようになるからだ。

ここまでの話はただ開発するだけであれば特に意識する必要はないのかもしれないが、
覚えておいていざその話題になった時なんとなく参加できると、なんだかエンジニアっぽい雰囲気が醸し出せるのかもしれない。

# Spring Bootではビルド時にBeanが作成される

Beanとはなにか？
簡単に言えばインスタンスである。（明確には異なるが大体はその認識であまり問題はないと思われる）
SpringではDIコンテナというものがあり、ビルドされた時に自動的にBean（インスタンス）を作り、
DIコンテナに格納してくれる。
つまりDIコンテナは生成されたインスタンスを入れておく容れ物ということらしい。
これも開発をするときに意識しなくても良い気がするが、理解はしておくと何か発展的なお勉強をした際の助けになるかもしれない。

ビルド時にクラスのBeanを作成してもらう方法としてはいくつか種類があるが、基本的には@⚪︎⚪︎の形で記述される、アノテーションというものを使用することでBean作成の対象とすることができる。
今回は@Componentあたりを使う方法を前提とする。

# DI：依存性の注入とは

Dependency Injectionの略
Springにおける基本思想であり、常にこれを意識した実装を行うのがSpringによる開発の基本である。
※ここでの「依存性」とはあるクラス（＝使う側）が他のクラス（＝使われる側）を利用している状態
使う側のクラスA、使われる側のクラスBが存在する際に、クラスBから作成されたBeanをクラスAのフィールド変数に代入するということらしい。
便利な点はいくつかあるらしいがいったんは概念だけの話としたいので割愛。

# アノテーション

## @Component

クラスからBeanを作成したい場合に記述するアノテーション
（ただしその中でも最もシンプルなもの）
例えば、「Hoge」クラスにこれを書いておけばビルド時に「hoge」という名称のBeanが生成される（頭文字が小文字になる）
ただし上記はデフォルトでBean生成を行った場合であり、名称の指定も可能。
@Component("Fuga")と記述した場合、「hoge」というBeanは作成されず、「Fuga」というBeanが作成される。（これにより頭文字を大文字にすることも可能）

## @Autowired

生成したBeanを呼び出す場合に記述するアノテーション
例えば、呼び出し元クラスで@Autowiredを記述してHoge型のフィールド変数を定義することで、
その変数にHogeのBeanが注入（Injection）される。

## @Componentの仲間

※基本的には一緒なのでお作法としてどこで何を使うべきかを把握しておく

### @Controller

クライアントとのデータ入出力を制御する（画面からHTTPリクエストを受け付ける）クラスに付与する

### @Service

ビジネスロジックの処理を行うクラスに付与する

### @Repository

データベースとのやり取りを行うクラスに付与する

# クラス依存とインターフェース依存

## クラス依存

クラス依存は、クラスAがクラスBを直接呼び出している状態
この状態でクラスBに修正が入りクラスの修正（クラスB→クラスC）やメソッドの修正（メソッドB→メソッドC）が入った際、呼び出す側のクラスAでクラスBの記述を行われている箇所も修正する必要がある。
このような構造は依存度が高く、柔軟性に欠ける。

## インターフェース依存

インターフェース依存はクラス依存とは異なり、クラスAからインターフェースBを呼び出している状態
（インターフェースBをimplementしているクラスBが存在する）
この状態でクラスBに修正が入りクラスの修正（クラスB→クラスC）やメソッドの修正（メソッドB→メソッドC）が入った際、同じくインターフェースBをimplementしたクラスCを作成することで、呼び出す側のクラスAに修正を行う必要がなくなり、「低依存」な状態にできるというメリットがある。

## Spring Bootでのインターフェース依存とDIの活用

Spring Bootでは、このインターフェース依存をさらに強化するために@Autowiredを利用して依存性の注入（DI）が可能。
@Autowiredを使うことで、Springがインターフェースを実装している適切なクラス（インスタンスやBean）を自動的に注入してくれる。

これにより、クラスAは具体的なクラスBやクラスCに直接依存することなく、インターフェースBを通じてSpringのDIコンテナにより最適な実装を受け取ることができる。この仕組みは、柔軟で拡張可能なアプリケーション設計を支援し、Spring Bootの強力な機能の一つと言える。

---

# おわりに

Gakken LEAP では教育をアップデートしていきたいエンジニアを募集しています。

https://gakken-leap.co.jp/recruit/

# 参考

https://euske.github.io/slides/spring202301/index.html
https://qiita.com/ist-a-ku/items/1d278619f241f4800bb2
https://qiita.com/shuncask/items/baf064182ce530ec26cd
https://qiita.com/ist-a-ku/items/c20d67140402634cd5db
https://www.issoh.co.jp/tech/details/2639/
#55 GAS スプレッドシートのタスクの締め切りをメールで通知させてみた

## はじめに
スプレッドシートでタスクを管理しつつ締め切りを通知することができたら便利だと思い、締め切り前にメールで通知するようGASを用いて設定してみることにしました。

## 手順
### スプレッドシートにタスクを入力する
スプレッドシートにタスクを入力します。
タスクは追加したいときに追加していってください。

<img alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3843084/f92cc910-fbba-3e9d-cf33-36969f500ae3.png" width="65%">

```
タスク：B3～
締め切り：C3～
状態：D3～
```
上記の場所のセルに入力します。

### Google Apps Scriptの設定
スプレッドシートのメニューバーから「拡張機能」＞「Apps Script」を開き、コード.gsを以下に書き換えます。

```js
function sendEmail() {
  // アクティブなスプレッドシートのシートを取得
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();

  // B列からD列までのデータを取得
  var data = sheet.getRange('B3:D' + sheet.getLastRow()).getValues();

  // 現在の日付を取得
  var today = new Date();

  // 行ごとにループ
  data.forEach(function(row) {
    // タスク
    var task = row[0];

    // 締め切り
    var dueDate = new Date(row[1]);

    // 状態
    var status = row[2];

    // 締め切りから2日前の日付
    var beforeDate = new Date(dueDate.getTime());
    beforeDate.setDate(dueDate.getDate() - 2);

    // 現在が締め切りの2日前より未来かつ締め切り未満、かつ状態が「未完了」の場合
    if (today.getTime() >= beforeDate.getTime() && today.getTime() < dueDate.getTime() && status !== '完了') {
      // ユーザーのメールアドレスを取得
      var emailAddress = Session.getActiveUser().getEmail();
      // メールの題名
      var subject = 'タスクの通知';
      // メールの本文
      var message = 'タスク:' + task + '\n締め切り: ' + Utilities.formatDate(dueDate, 'Asia/Tokyo', 'yyyy/MM/dd');
      // メールを送信
      MailApp.sendEmail(emailAddress, subject, message);
    }
  });
}
```
### 実行してみる
画面上部の「実行」を押下します。

<img alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3843084/a84d61da-9a75-aa25-0ab5-dcfccb8f04c5.png" width="80%">

すると、アクセス権限を求めるポップアップが表示されます。

<img alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3843084/5f0c1352-3ef4-9458-f149-873aa86d9b9d.png" width="50%">

先に進み「許可」押下でアクセス権限を許可してください。

実行が行われると自分のGmailアドレス宛にメールが届きます。
締め切りが2日前となったタスクの通知が確認できます。

<img alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3843084/8170571b-f543-3edb-dd85-aa1fd3bf1f57.png" width="45%">


### トリガーの設定
実行ボタンを押さなくとも、毎日自動で実行されるようにトリガーを設定します
画面左のメニューから「トリガー」を押下しトリガー画面を開きます。
トリガー画面の右下の「+ トリガーを追加」ボタンを押下し、以下のように設定します。
```
実行する関数：sendEmail
実行するデプロイ：Head
イベントのソース：時間主導型
イベントの種類：日付ベースのタイマー
時間の間隔を選択（分）：お好みで
エラー通知設定：お好みで
```
<img alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3843084/a072fdc5-0e9c-4e04-9be2-b06259c803b8.png" width="55%">

<img alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3843084/ef6823c2-3061-8bda-56bd-746207463c0b.png" width="80%">

保存すると設定した時間間隔で自動的にメールが送られるようになります。
時間ベースのトリガーのタイプを変更することで各週や各月で通知を送ることも可能です。


## 最後に
今回はスプレッドシートに登録したタスクをメールで通知させてみました。
アクティブなシートを指定しているためシートが複数あると対応できないなど改善できるところがあるので、修正していけたらと思います。
閲覧ありがとうございました。

出典：
https://coporilife.com/486/
https://note.com/yasushiiizuka/n/n0412668779ac
https://monoblog.jp/archives/6920
CentOS構築後yum,dnfコマンドエラーによりパッケージのDLが出来ない問題の対処備忘録

# 前置き
CentOSを構築完了後dnfやyumコマンドを使ってパッケージをDLしようとしたら下記のようなエラーが発生しました。

```
[taki@localhost ~]$ sudo yum upgrade
CentOS Linux 8 - AppStream                                                                            0.0  B/s |   0  B     00:00    
Errors during downloading metadata for repository 'appstream':
  - Curl error (6): Couldn't resolve host name for http://mirrorlist.centos.org/?release=8&arch=x86_64&repo=AppStream&infra=stock [Could not resolve host: mirrorlist.centos.org]
Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: Curl error (6): Couldn't resolve host name for http://mirrorlist.centos.org/?release=8&arch=x86_64&repo=AppStream&infra=stock [Could not resolve host: mirrorlist.centos.org]
[taki@localhost ~]$
```
```
[taki@localhost ~]$ sudo dnf install glibc-langpack-ja

CentOS Linux 8 - AppStream                      0.0  B/s |   0  B     00:00    
Errors during downloading metadata for repository 'appstream':
  - Curl error (6): Couldn't resolve host name for http://mirrorlist.centos.org/?release=8&arch=x86_64&repo=AppStream&infra=stock [Could not resolve host: mirrorlist.centos.org]
Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: Curl error (6): Couldn't resolve host name for http://mirrorlist.centos.org/?release=8&arch=x86_64&repo=AppStream&infra=stock [Could not resolve host: mirrorlist.centos.org]
[taki@localhost ~]$ 

```
**原因**
どうやらCentOSのサポート終了に伴い、Yum リポジトリの設定で、[base] に書かれたデータ取得先 URL がおかしいと言われているようです。

コマンドを正常に使用できるよう、リポジトリの記載内容を変更して対処します。

# 対処

Yum リポジトリの設定は、/etc/yum.repos.d/ 以下にあります。

[base] の URL は CentOS-Base.repo というファイルに記述されています。
元の URL を # でコメントアウトし、適切な URL を追記します。

```
sudo nano /etc/yum.repos.d/CentOS-Linux-BaseOS.repo 
```
**<リポジトリのリスト>**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/6b7e35a0-2519-4f3b-0c19-ae4320956f73.png)

**<修正前>**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/5a43769d-ddf7-ade6-b837-c9ce74e851bc.png)

下記コードを追加しmirrorlistをコメントアウトする
```
baseurl=http://vault.centos.org/$contentdir/$releasever/BaseOS/$basearch/os/

```
**<修正後>**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/bd3c9215-3e87-49f7-f0cb-b4c8bfb1a0d7.png)


上記の要領で下記それぞれのファイルにも実施していきます。

```
[taki@localhost ~]$ sudo nano /etc/yum.repos.d/CentOS-Linux-AppStream.repo 
[taki@localhost ~]$ 
[taki@localhost ~]$ sudo nano /etc/yum.repos.d/CentOS-Linux-BaseOS.repo 
[taki@localhost ~]$ 
[taki@localhost ~]$ sudo nano /etc/yum.repos.d/CentOS-Linux-Extras.repo 
```

ファイルの修正が終わった後、パッケージのDLが出来るか確認してください。

以上で設定は終了です。お疲れ様でした。
今日の関数: SUMIF

用途: SUMIF 関数は、指定した条件に一致するセルの合計を計算するために使用されます。特定の条件に基づいてデータを集計するのに便利です。

使用例:

=SUMIF(A1:A10, ">10", B1:B10)

この例では、範囲 A1:A10 のセルのうち、値が10より大きいセルに対応する B1:B10 のセルの値を合計します。

メリット:

条件に基づいた集計が簡単に行えます。
大量のデータから特定の条件に合致するデータを迅速に集計できます。
注意点:

条件は文字列として指定する必要があります（例: ">10"）。
条件に一致するセルがない場合、結果は0になります。
【Java】指定した開始位置から、指定したバイト数をStringで返す

### ■ 関数定義部分
```java
public static String Bytes_CUT(String str, int start, int get_length) {
```
#### 引数

１：str　
byte形式に変換して切り取る文字列全体。

２：start
str の何バイト目から切り取りたいかの指定

３：get_length
start から始めて、何バイトの値を取得したいか

#### コード
```java

/**
*   cut_start から、get_length 分の値を取得する
*/
    public static String Bytes_CUT(String str, int start, int get_length) {

        // string => byte へ変換
        byte[] get_def = str.getBytes(StandardCharsets.UTF_8);

        int cut_start = start - 1; // index 考慮用に -1 をした値
        int cut_end = (start + get_length) - 1;    // cut_start から、get_length 分の値を取得する


        byte[] result_def = new byte[get_length];
        int idx = 0;
        for (int i = 1; i <= 190; i++) {
            if (i >= cut_start && i < cut_end) {
                result_def[idx] = get_def[i];
                idx = idx + 1;
            }
        }

        // String で上で切り取った値を返す
        String return_str = new String(result_def, StandardCharsets.UTF_8);
        return return_str;

    }

```
#### Main 部分で関数使用
```java
String get_QR = scanResult.getContents();
String Get_CODE = Bytes_CUT(get_QR,30,11);
System.out.println("取得コード:::" + Get_CODE);

```
ネットワークデバイス完全ガイド：ルーター、スイッチ、ファイアウォールなどの役割を徹底解説！

#### 概要
ネットワークを構築する際、複数のデバイスが必要です。この記事では、ルーター、スイッチ、ファイアウォール、サーバー、クライアントPCの役割と機能を詳しく解説します。

---

#### 1. ルーター

- **説明**: ルーターは、異なるネットワークを接続し、データパケットを適切にルーティングする装置です。インターネット接続には欠かせません。
ほとんどの場合、LAN（ローカルエリアネットワーク）とWAN（ワイドエリアネットワーク）の間でデータを受け渡します。
- **特徴**: IPアドレスを基にパケットを転送し、複数のデバイスのインターネットアクセスを管理。
- **用途**: 家庭、オフィス、企業ネットワーク。

#### 2. スイッチ

- **説明**: スイッチは、LAN内でのデータパケットの転送を効率的に行う装置で、ルーターとともにネットワークの基礎を支えます。
複数のデバイスを接続し、ネットワークを構築します。
- **特徴**: データ転送速度が高く、パケットを宛先のデバイスに直接送信。
- **用途**: オフィス、データセンター。

#### 3. ファイアウォール

- **説明**: ファイアウォールは、ネットワークのセキュリティを守るために外部からの攻撃や不正アクセスを遮断する役割を持つ装置です。
主な機能としては、通信のフィルタリング機能・IPアドレス変換機能・遠隔管理/ログ監視機能があります。
- **特徴**: 外部ネットワークと内部ネットワークのトラフィックを監視し、ルールに従ってアクセスを制御。
- **用途**: 企業ネットワーク、セキュリティが重要な環境。

#### 4. サーバー

- **説明**: サーバーは、ネットワーク内でデータやリソースを他のデバイスに提供する中心的な役割を果たします。
主にファイルの共有・保存、メール送受信、Webページの閲覧等多岐にわたるサービスに用いられる。
- **特徴**: 大量のデータ処理、複数のクライアントにサービスを提供。
- **用途**: ウェブサーバー、ファイルサーバー、データベースサーバー。

#### 5. クライアントPC

- **説明**: クライアントPCは、ネットワーク上でサーバーに接続し、リソースやデータを利用するデバイスです。
基本的にインターフェースの役割を持ちます。
入力データや処理要求をサーバに送信し、サーバから受け取った処理結果をユーザーに提示します。
- **特徴**: 一般的なコンピュータとしてユーザーが操作し、ネットワークのリソースを利用。
- **用途**: オフィス、家庭での一般利用。

---

#### 総括
ネットワークデバイスは、それぞれ異なる役割を持ちながら、全体のネットワークの安定性やセキュリティを支えています。適切なデバイスの配置が、ネットワークのパフォーマンスと安全性を向上させます。

---
プログラミングにコミュニケーションは果たして必要なのか？〜実際にUniProで活動を始めて分かったこと〜

:::note warn
この記事はだいぶ前に書いてアドカレに使おうと思って予約投稿忘れていた記事です。
どうぞ笑ってください()
:::

どうもこんにちは、久しぶりです。

4ヶ月くらい更新をサボっていた(というか、忙しくてできていなかった)わけですが、ちょっと無性に書きまくりたい衝動が出てきたので書いてます…

## 結論

結論から言うと、**普通に要ります**。
なんでかっていうと、

1. 上達のためにいる
2. 共同開発のためにいる
3. みんなに見てもらうためにいる
この3つですね。それぞれどういうことか…

## 上達のため

まず、なんで上達のためにいるんやって思いますよね。
ここで、プログラミングならではのことを書きたいと思います。

### プログラミングは本や知識だけではならない

プログラミングって手を動かさないとなんですよ。その上で、**技術を盗むというのが非常に大切**です。

他の人のやっていることを真似て、それを自分のものにしていく、それが一番の上達方法だと思います。

### 経験を積むべき

これは、OSSに参加してみたり、という部分になりますね。この話は、次の共同編集の部分でも取り扱うのでここでは一旦割愛します。あとで詳しく書きます。

## 共同開発のため

これは、まぁ、よくあるOSSとか、UniProみたいなところでの話ですね。

### OSSの大切さ

栄えているOSSプロジェクト(オープンソースプロジェクト)は、やはり、実力派の方が非常多いです。なので、こここそ、**技術を盗むチャンス**なのです。

他にも、OSSにGitHubなどで、プルリクエストを投げると、コードレビューがもらえます。
それだけで、今まで自分がわからなかった、**自分のコードの改善点**が見えてきます。

### 何かプロジェクトを立ち上げるとき

UniProみたいなのを立ち上げると、サーバーを提供してくれる人が出てきたり、開発を一緒に進めてくれる人が出てきます。
これが、ものすごく楽で、楽しいです。

こういう時、運営目線として、人を包容する力や、いわゆる、大人の対応というのが必要になってきます。

## 総括

やっぱり、**コミュニケーションは必須**ですね。

コミュニケーションを重視していない人がいたら、これ読ませてやってください。
自ずと何をすればいいかはわかると思います。

コミュ力アップのことは、Qiitaではなく、今度noteの方に書きます！！
そちらも、よければご覧ください！！
(※かけたら貼ります...)

ではでは...
File.deleteのちょっとしたテクニック

## はじめに

RubyのFile.deleteメソッドを使うときのちょっとしたテクニックを紹介します。

## 環境

Ruby2.6

## 内容

File.deleteはファイルを削除するメソッドです。データベースから読み込んだ内容をテキストファイルに書き込みをするような場合、同じ名前のファイルが既にあれば、このメソッドを利用して事前に削除します。

このメソッドをそのまま実行すると、つぎのような場合にエラーが発生することになります。

#### 削除対象のファイルがないとき

ないファイルに対して削除しようとするとエラーが発生します。そのようなファイルはありませんという内容のエラーです。

Rubyにはなぜか、VBにはあったエラーが発生した行の次の行から処理を再開させる、Resume Nextに該当するメソッドがありません。（これ便利だったんだけどな・・・）

例外に飛んだ後、エラーに該当するerrnoでキャッチして、そこでなんらかの処理をしなくてはいけないことになります。

Rubyには代わりに、エラーが発生した行に戻る、retryといったメソッドがあります。例外の中で何もせずにretryをすると無限ループに陥ることになります。例外で削除対象のファイルをオープン＆クローズさせてから、retryすると削除してくれます。

```
No such file or directory
errno:2
```

#### ファイルが開かれているとき

削除対象のファイルがオープンされたままの状態で、削除するとエラーになります。ファイルが開かれた状態になっていますといったエラーです。強制削除させるようなオプションがあればいいのだが、残念ながらありません。

例外処理でエラーに該当するerrnoをキャッチして、オープン＆クローズさせてから、retryすると削除処理が正常に流れてます。

```
Text file busy
errno:26
```

#### ちょっとしたテクニック

File.deleteするときは、エラーが発生した都度、例外で何らかの処置をするのではなく、始めから、削除対処のファイルをオープン＆クローズさせてあげればこと足ります。

```sample.rb
fil = File.open("hoge.txt","a")
fil.close
File.delete("hoge.txt")
```

オープン＆クローズを付けるだけで、想定される例外エラーは発生しなくなります。それでも、想定外のエラーが発生したときのために、例外処理はつけておいたことに越したことはないでしょう。

#### 《疑問・その１》削除対処のファイルが初めからオープンされていた状態で、再度オープンさせてもエラーにならないのか？

エラーになりません。Rubyではどうやら、ファイルをオープンさせるときに、全てのファイル番号に対して、全てクローズさせてくれる処理が内部的に施されているようです。（この機能VBにはなかった）

#### 《疑問・その２》ないファイルをオープンさせてエラーにならないのか？

エラーになりません。ないファイルをオープンさせると、0KBの空ファイルが作成されるだけです。ないファイルを削除させる場合は、0KBの空ファイルを事前に作成してあげて、削除処理を流してあげればいいのです。削除対処のファイルがある場合は、そのままオープンしてクローズされるだけです。

#### FileUtils を使う　（補足）

FileUtilsを使ってファイル削除をすることもできます。force: trueというオプションを使うと、削除対象のファイルが存在しない場合、エラーにならずスルーしてくれます。こちらを使った方が幾分シンプルにコーディングができます。ほとんどの方はこちらをひいきに使っていることでしょう。

```sample.rb
FileUtils.rm(file, force: true)
```
(6話) 熱波師おかん、SnowPro Core壮絶な不合格にご飯が喉を通らず！

こんにちは、サウナ熱波師を目指しながらSnowflakeの勉強に励んでいるおかんです。

今日は、私が挑戦したSnowPro Core試験での壮絶な不合格体験についてお話ししたいと思います。正直、試験の結果を見たときはショックで数日、ほんとにご飯が喉を通りませんでした。でも、この経験を通して学んだことや感じたことを共有することで、同じように頑張っている皆さんの励みになればと思います。

ひょんなことからSnowflakeに出会って、どこか魅了され、「絶対に資格をとりたい！」と思うようになりました。最初に「ええ！？そんなことある？」と思ったのは、資格試験なのにどんな大きな本屋にも対策の参考書も問題集もないこと。知人に聞いたところ、まだ新しい技術ではよくあることらしいです。最先端を追いかけているっぽくて、逆にやる気につながりました。そして、仕事やプライベートの合間を縫って約1年近く、「これならいける！」とある程度の自信を持って本番に挑みました。

勉強に使った教材は、こちらです。  

https://www.udemy.com/course/ultimate-snowpro-core-certification-course-exam/?couponCode=ST11MT91624A

日本語の字幕もついているし、順番に機能の紹介をしてくれるので、皆さんのブログでもよく紹介されていた教材。私もこれを頼りに頑張りました。それに加えて、Snowflake本体のページも何度も読み込み、時には夜遅くまで勉強するを時も。サウナで熱波を受けながら、ブツブツと暗記項目を呟いたこともあります。

ちなみに、試験の申し込み方法がさっぱりわからず、そこは知人にかなり助けてもらいました。そして迎えた試験当日。某所のテストセンターに向かい、初めての受験で少し緊張していましたが、「これまで頑張ってきたんだから大丈夫！」と自分を奮い立たせました。

受付を済ませて試験室に案内され、静かな部屋でパソコンの前に座り、いざ試験開始。最初の数問は順調でしたが、進むにつれて見たことのない問題や、曖昧な記憶の部分が出てきて、焦りが増してきました。冷や汗が止まらず、頭が真っ白に。試験時間はあっという間に過ぎ、終了ボタンを押すとその場で結果が表示されます。スコアを見て愕然。合格点の半分ほどしか取れず、思わず「嘘でしょ…？」と画面を二度見してしまいました。

家に帰ってもショックが大きすぎて、せっかく作った夕飯もほとんど手をつけず、家族にも心配をかけてしまいました。「何がダメだったんだろう？」「勉強が足りなかったのかな？」と自己嫌悪に陥り、そこから2週間ほどはあまり記憶がありません。

ようやく立ち直り始めた頃、そしてさらに、受験料の2万5000円強が戻ってこない現実にも直面。これはもう痛すぎる…。ここで気持ちが完全に折れそうになりました。「やめた方がいいのか？」「もう一度挑戦するべきか？」と、かなり迷いました。

それでも、ここで諦めるわけにはいかないと思いました。私がなんとなく乗りで目指したこの資格は、取得をもってゴールです。失敗しても、それを学びに変えれば次はもっと強くなれるはず。新しい目標に向かって、気持ちを切り替えることにしました。
じっさい、「こう聞かれるのか、こんな言い回しかー」と試験で印象的だった内容はかなり頭に残っています。

ということで、私は再チャレンジを誓いました。教材をもう一度見直し、合格者のブログを片っ端から読み漁り、新たな勉強計画を立てて再スタートです。次こそは、きっと合格してみせる！そんな強い気持ちで、再び勉強の日々が始まりました。


最後まで読んでいただき、ありがとうございました。次回は合格の報告ができるよう、引き続き努力していきます。それでは、またお会いしましょう！
PlantUMLを Actionsで画像化して UMLレビューを簡易化する

## 課題解決

Plant UML を使ってデザインすることが多いが、Plant UMLは [Mermaid](https://mermaid.js.org/) の様に GitHub連携されていないので、IDE 上では図が表示されるものの、GitHub上では`.puml` が図化されない。これは特にレビュー時に問題で、pumlファイルをコードとしてレビューするか、一旦ブランチを落としてきてローカル上の IDEで確認しなければならない。可能であれば GitHub上に画像表示されていて欲しいところである。

この対応として、Docker コンテナを用いて puml → png  と出力する機能と、push 時にそれを自動実行する Actionsを用意した。汎用的に利用できるので利用してみて欲しい。

ディレクトリ構成は以下の様になっていることを想定する。
```bash
├── Makefile
├── README.md
├── _docs/
│   └── uml/
│       ├── img/
│       ├── Dockerfile
│       ├── sequence.puml
│       └── class.puml
└── compose.yml
```
- `_docs` ドキュメント全般を格納
- `_docs/uml`  `*.puml`ドキュメントを格納
- `_docs/uml/img` `*puml` ドキュメントから生成した `png` イメージを格納


## Dockerfile

Dockerfile の中身は以下のようになっている。内部では GitHubの plantuml からアーティファクトをダウンロードしてそれを元にイメージを生成している。ダウンロードURLは `JAR_URL` として定義しているが、時間の経過とともに最新のURLを参照して欲しい。

`_docs/uml/Dockerfile`

```dockerfile
# ベースイメージを指定
FROM ubuntu:latest

# パッケージの更新
RUN apt-get update && apt-get install -y \
    default-jre \
    graphviz \
    plantuml \
    curl \
    fonts-noto-cjk

# 作業ディレクトリの指定
WORKDIR /app

ENV JAR_URL='https://github.com/plantuml/plantuml/releases/download/v1.2024.7/plantuml-mit-1.2024.7.jar'

RUN curl -L -o 'plantuml.jar' "${JAR_URL}" && \
    chmod +x plantuml.jar

WORKDIR /app/uml

# コンテナ実行
ENTRYPOINT ["java", "-jar", "../plantuml.jar"]
CMD ["-tpng", "-o", "./img", "**/*.puml"]

```

## Makefile

`Makefile` 上では Dockerfile 操作に関する各種エイリアスを定義している。これらは GitHubActions から利用されるが、手動での実行の際も便利である。

```makefile
.Phony: build run connect compose-run clean

build:
	@ docker build -t puml _docs/uml

run:
	@ docker run -v ./_docs/uml:/app/uml puml

connect:
	@ docker run -it --entrypoint bash -v ./_docs/uml:/app/uml puml

compose-run:
	@ docker compose run --rm puml

clean:
	@ rm _docs/uml/img/*.png

```

## Workflow定義

GitHub Actions の定義は以下の様に記載する。基本的には `main` ブランチに push した段階で png イメージが自動生成される。

`.github/workflows/plantuml.yml`

```yaml
name: Fix Commit

on: push

jobs:
  fix_commit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Fix code
        run: |
          make build
          make run
      - name: Commit changes
        run: |
          git config user.name "GitHub Actions"
          git config user.email "actions@github.com"
          git add .
          git commit -m "update uml images"
          git push
```

## まとめ

以上の工程で `_docs/uml`ディレクトリ上の `*.puml` ファイルが全て `main`への `push`時に画像化される仕組みができあがる。

シンプルな仕組みだが、レビュー時に便利なので試してみて欲しい。
マイGPTを使って反社調査を行う

## マイGPTとは
英語版では`My GPTs`と表示されますが、本記事では`マイGPT`と表記します。

マイGPTは、OpenAIのChatGPTを使って、誰でも簡単にカスタムチャットボットを作成できるサービスです。プログラミングの知識がなくても作成可能です。

**My GPTs**を利用するには、有料の**ChatGPT Plus**か、それ以上のプランに加入する必要があります:point_up_tone1:
![myGPTpng.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/c4eb7f9b-59b4-d5a9-6560-845a6193c0f9.jpeg)

## 早速作ってみよう
お馴染みな[ChatGPT画面](https://chatgpt.com/)の右上からメニューを開いてください、`マイGPT`をクリックしてください。
![2E91FE27-D8F8-4E7A-AA7F-03FE6165331B.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/097ef42d-95ec-74d2-7cdd-948ad853c984.jpeg)

開いた画面で`GPT を作成する`をクリックしてください。
![8AA9D712-4BE5-4D20-9635-7B31CEF7A5AB_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/87d6a198-a360-8c91-8100-dd675adfb24b.jpeg)

開いた画面がワークスペースになります。
![E1D32F09-F5F3-4A53-B519-74972D68A9B4.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/0a081669-bc61-b6c6-5961-0f59680770c4.jpeg)

左は`GPT Builder`というサポートツールになります、会話形式でマイGPTを作成できます。![FE027D08-E731-4CB4-B115-2DAF658F0E38.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/d8e91d43-a9d4-06d4-11bd-7ea5288ac0f9.jpeg)
右側はプレビュー機能、作られた`マイGPT`をテストすることが可能です。
![11D33681-EDB7-47A8-9878-BDD62BBD12AA.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/b05a39b8-66c0-958c-756a-7b9adae4921f.jpeg)

構成タブを開けば、`GPT Builder`で構築した内容を確認できます、最も簡単なマイGPTの構築はここまでで完了です。

## 深掘り

`マイGPT`の回答に大きく影響するカスタマイズ可能な機能は、以下の3つです。
- 指示
    - 指示はプロンプトのことで、`マイGPT`の動作をコントロールすることができます。
- 知識
    - 知識はナレッジベースやRAGのことを指し、`マイGPT`が最も優先的に参照する外部リソースとなります。
- ウェブ参照
    - 知識で十分な回答が得られない場合、ウェブ検索を行う機能です。どのサイトを検索に使用したかを確認することができます。
- アクション
    - 例としてAWS Bedrockのエージェントアクショングループのような機能です。うまく活用することで、できることの幅が大きく広がります。複数のアクションを登録することも可能です。

これらの機能を活用して、実用的な`マイGPT`を作成してみましょう。

## 反社調査マイGPT作ってみよう

### 指示
内容は公開できませんが、社内にある反社調査用のマニュアルのフォーマットを少し変更して、ほぼそのまま利用しています。
例えば、無償で一度限り、ある会社から低額なものを贈与された際には、反社調査を行わなくても問題ありません。
その他、出力を制御するフォーマットや判断の順序に関する指示も含まれています。


### 知識
社内にホワイトリストがあります、それを知識として使用しました。

### ウェブ参照
利用します。

### アクション
SNS検索できるAPIをApiGatway + Lambdaで実装しました。

:point_up_tone1: 実際動作確認してみましょう

![C1DB9D78-76C4-4B27-AEF4-2DD13AC71840_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/de8a9c32-e229-524f-a020-94d512a47363.jpeg)
- マニアル通りの動作です。

![1F8D0F2C-20B3-4400-8093-3C8FC988E5E5_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/a68368b6-bb1a-d5eb-bca0-24fbfdabb703.jpeg)
- 知識を利用した回答です。

![7735707A-8FDA-4ED8-B8FC-03EC36146CB7.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/50af9c7e-97c0-b2c2-583c-9338539a130e.jpeg)
- ウェブ情報参照してくれました。

![DEC26A05-E32A-44C0-8974-E8445F305EDC_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/19fc5ca8-5565-a258-e47c-8b30fb90ea8a.jpeg)
- SNS情報検索指示する場合、アクションを利用しました。

## 感想
誰でも気軽にカスタマイズできる点は良いと思いますが、出力の細かい制御やアクションチェーンの実行が難しいと感じました。
アクションとして提供されるAPIはOpenAPI形式のドキュメントが求められるため、今後、FastAPIの評価がさらに高まるのではないかと思います。
0から統計の勉強 分散と標準偏差

# 学習サイト
統計web
- https://bellcurve.jp/statistics/course/

# 分散
- データがどのぐらい平均の周りにバラついているかを表したもの
- 分散が小さいほど、データの値は平均値に集まっており、大きいほどデータの値が平均値からバラついていることを表す
- <font color="Red">**分散と平均を足したり、比較したりすることができない点**</font>を注意しなければいけない
    - 理由としては、以下に示すが各データを2乗したものを用いているためである

例：ある実験を行い、次の2つのデータが得られた。AもBもどちらも平均は3.5であるが、この2つのデータのばらつき具合は似ていると言えるか

| データA | データB |
| - | - |
| 1 | 3.5 |
| 2 | 3.5 |
| 3 | 3.5 |
| 4 | 3.5 |
| 5 | 3.5 |
| 6 | 3.5 | 
| 合計=21 | 合計=21 |
| 平均=3.5 | 平均=3.5 |

以下の3つの値を用いて、2つのデータの平均値からのばらつき具合を比較する
1. 「平均値からの各データ」の平均値
1. 「平均値からの各データの差の絶対値」の平均値
1. 「平均値からの各データの差の2乗」の平均値


### 1. 「平均値からの各データ」の平均値
したの表は平均値とそれぞれのデータとの差をまとめたものである

| データA | 平均値からの差 | データB | 平均値からの差 |
| - | - | - | - |
| 1 | 2.5 | 3.5 | 0 |
| 2 | 1.5 | 3.5 | 0 |
| 3 | 0.5 | 3.5 | 0 |
| 4 | -0.5 | 3.5 | 0 |
| 5 | -1.5 | 3.5 | 0 |
| 6 | -2.5 | 3.5 | 0 |
| 合計=21 | 合計=0 | 合計=21 | 合計=0 |
| 平均=3.5 | 平均=0 | 平均=3.5 | 平均=0 |

この差の平均はデータAもデータBも0であった

ここで算出した「平均値と各データの差」のことを<font color="Red">**偏差**</font>という
- 「平均値より大きいデータの偏差の和」と「平均値より小さいデータの偏差の和」が打ち消しあうために、<font color="Red">**偏差の和は常に0である**</font>
- したがって、この方法ではデータのばらつきを比較することはできない


### 2. 「平均値からの各データの差の絶対値」の平均値
比較する値が必ず0以上となるように平均値とそれぞれのデータとの差の絶対値の平均を考えてみる

| データA | 平均値からの差の絶対値 | データB | 平均値からの差の絶対値 |
| - | - | - | - |
| 1 | 2.5 | 3.5 | 0 |
| 2 | 1.5 | 3.5 | 0 |
| 3 | 0.5 | 3.5 | 0 |
| 4 | 0.5 | 3.5 | 0 |
| 5 | 1.5 | 3.5 | 0 |
| 6 | 2.5 | 3.5 | 0 |
| 合計=21 | 合計=9 | 合計=21 | 合計=0 |
| 平均=3.5 | 平均（＝平均偏差）=1.5 | 平均=3.5 | 平均（＝平均偏差）=0 |

絶対値をつけた偏差の平均は、データAの1.5の方がデータBの0より大きいことから、データAの方が平均値からばらつき具合が大きいことがわかる。
- この値を<font color="Red">**平均偏差**</font>と呼ばれる

<font color="Red">**しかし、絶対値の計算は絶対値記号を外すために場合わけをする必要があるため、数学的に面倒であるというデメリットがある**</font>


### 「平均値からの各データの差の2乗」の平均値
- 最後に、各データと平均の差を2乗したものの平均を考える
- 二乗しているため、必ず0以上となる
- <font color="Red">**分散はここに該当する**</font>

```math
n個のデータをx_i(i = 1, 2, ・・・, n)、その平均値を\bar{x}とすると、分散の公式は以下の通りである
```
```math
V = \frac{1}{n}\sum_{i=1}^{n}(x_i - \bar{x})^2
```

今回の例題のAの場合で実際に求めようとすると、以下の手順で求めることになる
#### 1. 各データの平均値からの差を求める
```math
(1 - 3.5), (2 - 3.5), (3 - 3.5), (4 - 3.5), (5 - 3.5), (6 - 3.5)
```

#### 2. 1で算出した値をそれぞれ2乗する
```math
(1 - 3.5)^2, (2 - 3.5)^2, (3 - 3.5)^2, (4 - 3.5)^2, (5 - 3.5)^2, (6 - 3.5)^2
```

#### 3. 2で算出した値を全て足す
```math
(1 - 3.5)^2 + (2 - 3.5)^2 + (3 - 3.5)^2 + (4 - 3.5)^2 + (5 - 3.5)^2 + (6 - 3.5)^2
```

#### 4. 3で算出した値をデータ数で割る＝分散
```math
{(1 - 3.5)^2 + (2 - 3.5)^2 + (3 - 3.5)^2 + (4 - 3.5)^2 + (5 - 3.5)^2 + (6 - 3.5)^2} \div 6 = 2.9
```

上記の通り計算を行うとデータA、データBの分散は次のようになる
```math
\displaylines{
・データAの分散：V_A = 2.9 \\
・データBの分散：V_B = 0
}
```

したがって、<font color="Red">**データAの方がデータの値が平均値からばらついている**</font>ことが証明された


# 標準偏差
- standard deviation
    - SDと訳されることもある
- 分散の平方根
    - 分散の正の平方根であることから分散を以下のように表すこともある
```math
\sigma^2
```
- これにより、分散ではできなかった足したり比較したりすることができるようになる

```math
\displaylines{
標準偏差 = \sqrt{分散} \\
\sigma = \sqrt{\frac{1}{n}\sum_{i=1}^{n}(x_i - \bar{x})^2}
}
```

先ほどの分散の標準偏差を考えると以下の通りである
```math
\displaylines{
・データAの標準偏差：\sigma_A = 1.7 あるいは SD_A = 1.7 \\
・データBの標準偏差：\sigma_B = 0 あるいは SD_B = 0
}
```

標準偏差を見ても、分散とう同様にデータAの方が大きいことから、**データAの方がデータBよりもばらついている**ことがわかる
自宅サーバの構成について

# 概要
サーバを構築するためのパーツが決まったのでメモ程度に記載する
※マンションの専用回線を使用していてポート解放ができないので
自宅のLAN内でのみ使用する予定。(行く行くは開放したい)

# パーツ構成
* OS : Ubuntu Server 24.04
* CPU : inteli5 6500
* マザーボード : MSI Z170-S01
* メモリ : 16GB
* SSD : 500GB
* HDD : 500GB(バックアップ用)
* 電源 : 玄人志向 KPPW-L5-400W
* ケース : レベルファイブのケース

総額は19800円
記憶媒体以外メルカリやヤフオクで揃えたため安くおさまった。

ただ小型のPCにするつもりがつもりだったが誤ってATXのマザボを購入・・
拡張できるしプラスに捉えよう～


# 今後
パーツが揃い次第組み立ててOSを導入していきたいと思う。
久しぶりの自作PCなので電源がうまくさせるか不安だ・・

完成したらユーザ追加したりクライアントPCからSSHできるように設定したり
何を初期設定するのか調べとかないと。
パンくずリストについて

## 役割
ユーザ自身の現在位置と辿ってきたルートを示すもの

## 種類
### 位置型パンくずリスト
一番目にするパンくずリスト。
Webサイト内の階層構造においてユーザーが現在どの場所にいるか示す。

【弊社HPより引用】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794537/c90ca160-0920-82f3-d99c-8c898b7b2c14.png)

### 属性型パンくずリスト
通販サイトで良く使用されているパンくずリスト。
ユーザーの操作によって絶えず変化して検索フィルタのような機能を持つ。

【通販サイトCreemaより引用】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794537/5a1b223b-7742-6986-fe5b-68f8868f37b7.png)

### パス型パンくずリスト
単にユーザーが辿ってきたものをリスト化したパンくずリスト。
「履歴型のパンくずリスト」とも呼ばれる。

## 設置するメリット
 -  SEO効果
 -  ユーザビリティの向上
 -  クローラーの巡回にも好影響


## 参考文献
https://www.mediatech.jp/

https://www.creema.jp/

https://seolaboratory.jp/92481/#:~:text=%E4%BD%8D%E7%BD%AE%E5%9E%8B%E3%83%91%E3%83%B3%E3%81%8F%E3%81%9A%E3%83%AA%E3%82%B9%E3%83%88%E3%81%A8%E3%81%AF%E3%80%81%20Web%E3%82%B5%E3%82%A4%E3%83%88%E5%86%85,%E3%81%A7%E5%88%A9%E7%94%A8%E3%81%95%E3%82%8C%E3%81%A6%E3%81%BE%E3%81%99%E3%80%82
rex0220 計算式プラグイン カナ小文字を大文字に変換

[計算式プラグイン](https://qiita.com/rex0220/items/ae83c6d5ce50ff7a9a73)で、カナ小文字を大文字に変換します。

# 概要

計算式プラグインで、小文字のカナを大文字に変換してみます。
アルファベットの upper 関数のように、簡単に変換できる関数が無く、小文字のカナを1文字ずつ大文字に変換します。

変換前
"ァAィBゥCェDォEャFュGョHッIヮJァAィBゥ"

変換後
"アAイBウCエDオEヤFユGヨHツIワJアAイBウ"

変換例：　
![2024-09-18_13h44_23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/a11a7e03-66b1-e479-5ae3-c06fc7912668.png)

# 計算式

処理の流れ
low 配列にある小文字のカタカナを一つずつ、対応する upper 配列の大文字カタカナに置き換えます。
すべての置換が終わると、最終的な文字列（大文字に変換されたもの）が出力されます。

- str: 元の文字列。例に出ているのは「ァAィBゥCェDォEャFュGョHッIヮJァAィBゥ」
- low: 小文字のカタカナ配列
小文字のカタカナが定義されています（「ァ」、「ィ」、「ゥ」など）
- upper: 対応する大文字のカタカナ配列。これが変換先
- ARRAY_MAP: low の配列（小文字カタカナ）を繰り返し処理
    - x: 配列内の現在の要素（小文字のカタカナ）
    - idx: 現在のインデックス（配列内の位置）
    - FSET: str の中の x（小文字）を upper 配列の対応する要素（idx を使って）で置換
- str: 最終的に変換された str が返されます

```.js
LET(str,"ァAィBゥCェDォEャFュGョHッIヮJァAィBゥ",
  low,ARRAY("ァ","ィ","ゥ","ェ","ォ","ャ","ュ","ョ","ッ","ヮ"),
  upper,ARRAY("ア","イ","ウ","エ","オ","ヤ","ユ","ヨ","ツ","ワ"),
  dummy,ARRAY_MAP(low,x,idx,
    FSET(str,REPLACEALL(str,x,ARRAY_GET(upper,idx)))
  ),
  str
)
```

または、ARRAY の代わりに SPLIT で記述

```.js
LET(str,"ァAィBゥCェDォEャFュGョHッIヮJァAィBゥ",
  low,SPLIT("ァィゥェォャュョッヮ",""),
  upper,SPLIT("アイウエオヤユヨツワ",""),
  dummy,ARRAY_MAP(low,x,idx,
    FSET(str,REPLACEALL(str,x,ARRAY_GET(upper,idx)))
  ),
  str
)
```
投稿 79 「cd」change directory（ディレクトリを変更する） 2024/09/18

本日の勉強時間　　H



cd は、change directory（ディレクトリを変更する）の略。

ターミナルや、コマンドラインで現在作業しているディレクトリ（フォルダ）を移動するためのコマンドです。cd コマンドを使うことで、別のディレクトリに移動し、そのディレクトリ内でファイル操作や実行を行うことができます。

-------------------

「用語確認」
▪️コマンドライン (Command Line)
コマンドラインは、ユーザーがコンピュータにコマンド（命令）を入力し
テキストベースでコンピュータに指示を出すインターフェースのこと。
GUI（グラフィカルユーザーインターフェース）が普及する前の時代、コマンドラインはコンピュータを操作する主要な手段でした。
CLIは（コマンドラインインターフェース）

特徴：
テキストベースの操作: キーボードでコマンドを入力し、実行結果がテキストとして表示。
柔軟な操作: ファイルの操作やプログラムの実行、ネットワークの設定など、細かい操作ができます。


▪️ターミナル (Terminal)
ターミナルは、コマンドラインを使うためのアプリケーションや環境のこと。

言い換えると、ターミナルはコマンドラインにアクセスするためのウィンドウやプログラムを指します。

様々なターミナルアプリ: macOSの「ターミナル」、Windowsの「PowerShell」や「Command Prompt」、Linuxの「GNOME Terminal」など、さまざまなOSでターミナルアプリがあります。

シェルの実行環境: ターミナルの中で「シェル」と呼ばれるプログラムが動作しています。シェルは、コマンドを解釈し、コンピュータに指示を送る役割を持っています。bash や zsh などが代表的なシェルです。


-------------------




cdの使い方
特定のディレクトリに移動する

例えば、/Users/miyazakiryouta/Documents というディレクトリに移動する場合：
```
cd /Users/miyazakiryouta/Documents
ホームディレクトリに戻る
cd コマンドを単独で実行すると、ホームディレクトリ（通常は ~）に移動します：
```

-注意点-
cd の後に続くパスは、移動先のディレクトリのパスです。絶対パス（ルートからの完全なパス）や相対パス（現在のディレクトリからのパス）を使用できます。
存在しないディレクトリを指定すると、No such file or directory というエラーが表示されます。







例: コマンドラインで以下のような操作も行います。
ls：ディレクトリ内のファイル一覧を表示
cd：ディレクトリを移動
mkdir：新しいディレクトリを作成