OmniAICreator/Qiita-1.07M huggingface dataset:
PowerApps galleryをタイトルをつけて、横スクロールに

# 完成イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368087/e7351488-b13a-3e77-8664-908e4337d9f1.png)
# コントロール設置方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368087/1749fc3f-219a-b583-bd1c-edc5f989a80e.png)
# galleryのプロパティ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368087/a1f8fb83-ee9a-9981-2634-23536187e81a.png)
# 縦コンテナのプロパティ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368087/bbb70d0c-c002-9e58-bf45-193c14c47ae1.png)
# 横コンテナのプロパティ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368087/56abca2b-df41-6227-eb53-8f6444b09bf6.png)
AIの影の部分: リスクとその対策

# AIに潜むリスクとはなにか？

とても便利なAIですが、AIには<font color="red">**様々なリスク**</font>があります。
そのため使うことに抵抗を感じる方も多いのではないでしょうか。
**実際にどのようなリスクがあり、対策法があるのか**調べてみました。

### 潜んでるリスク
:::note 
**・情報漏洩：AIに入力された情報が第三者に漏れる可能性がある**

**・著作権：生成AIが他人の著作を基にコンテンツを生成し著作権侵害のリスクがある**

**・誤情報の拡散：AIが間違った情報を提供しその結果として誤解が生まれることがある**

**・プライバシーやセキュリティの問題：AI利用によって個人情報が不適切に扱われる可能性がある**
:::
他にも**人種差別**などの**社会的問題**にも影響があります。

今回は<font color="red">**上の二つ**</font>について書こうと思います。

## 情報漏洩

AIは入力されたデータを処理する際に、そのデータが**適切に管理されていないと、意図せず第三者に漏れるリスク**があります。


### 実際に合った事例
2023年に<font color="red">**ChatGPTでバグによってユーザーのチャット履歴のタイトルがほかのユーザーに表示される事態**</font>がありました。
このように、ユーザーが意図せずに漏洩するリスクはありますが<font color="red">**具体的な対策は以下の通り**</font>です。

:::note warn
**・API連携**
**・機密情報など個人情報などを入力しないようにする**
:::



### API連携の利用
APIとは<font color="red">**アプリケーション同士を連携するインターフェイス**</font>のことで、生成AIを**自社のアプリケーションと連携**させれば、APIを介して**生成AIのサービスと通信を行う**ようになり生成AIに**入力内容が学習されなくなります。**
AIによっては**入力情報を学習させない設定の導入も可能**なモデルや設定があります。

実際ChatGPTには**一時チャット**という機能がありこれを**オンにすることによって一時学習を防げます。**

![スクリーンショット 2024-09-27 095448.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3875902/78424dad-7c13-940e-9a05-a1d6d94ef788.png)

それでも心配の場合は**機密情報など漏洩されたくない情報を入力せずに使える範囲で使用を検討**するのも一つの手だと思います。

[**業務効率化AIのおすすめはこちら**](https://mdown.ai/content/054ae91e-01e5-4ae9-9c9d-69b575ba8c5c)



## 著作権

生成AIは**既存の著作物を学習データとして使用**しています。

次に、生成AIによって生成されたコンテンツが既存の著作物を侵害するかどうかは
<font color="red">**以下の3つの要件によって判断されます。**</font>

:::note 
**著作物性: 既存の画像やイラストが著作権によって保護されていること。創作的な表現である必要があります。**

**類似性: 既存の著作物と見た目や内容が似ていること。具体的には、どれだけ似ているか、どの部分が同じかを考慮します。**

**依拠性: 生成されたコンテンツが他の著作物を参考にして作られた場合。既存の著作物の影響を受けているか。**
:::
これらの要件が満たされる場合、**著作権侵害が成立**します。特に、類似性については<font color="red">**「表現上の本質的な特徴」**</font>を**直接感得できる場合**に認められます。

日本では、<font color="red">**2019年に改正された著作権法**</font>により、<font color="red">**AIがデータを学習する際、著作物を「情報解析」目的で使用する場合**</font>は、**著作権者の許可が不要**とされています。ただし、**この使用はデータ解析などに限定**されており、<font color="red">**商業利用には制限**</font>があります。

### 実際に合った事例


<font color="red">**2024年OpenAIとニューヨーク・タイムズの間で著作権問題が発生**</font>
ニューヨーク・タイムズは、<font color="red">**OpenAIが許可なく数百万の記事を使用してAIモデルを訓練した**</font>と主張し、**法的救済と知的財産保護のための商業契約**を求めています。</font>

:::note warn
**・監査・フィルタリング**

**・許諾取得**
:::

### 監査・フィルタリング

作品が似てしまうことは影響を受けたものによっては、避けられないことですよね。
そのため都度<font color="red">**生成されたコンテンツが既存の作品と似ていないか、データをチェックし問題を避けるよう**</font>にしましょう。

他にも**既存の作品を使用したい場合は**<font color="red">**必ず許可を取ることでトラブルを避ける**</font>ことができます。

## 最後に
いかがでしたか？仕事内容によっては使わないこともあるかもしれませんが、今後のAI利用に備えるためにも、リスクを理解しておくことが重要です。
もし生成AIを使ったプロジェクトに参画する際はデータチェックを怠らないように気を付けていきたいです。

最後までお読みいただきありがとうございます。
[**業務効率化AIのおすすめはこちら**](https://mdown.ai/content/054ae91e-01e5-4ae9-9c9d-69b575ba8c5c)
Atomic Simulation Environmentの使い方: VASPでのDFT計算の詳細

## ASEによるVASPの詳細設定
### はじめに
* 以下は、ASEでVASPの設定を行いDFT計算を実行するためのメモ
* `ase.calculators.vasp`の`VASP`クラスの変数を通じて設定する
* 計算条件は基本的にVASPのインプットファイル(`INCAR`)に反映される。INCARタグの意味はここでは説明しない
* 過去の記事(エネルギー計算)を参照してください

### 計算の設定
* VASPを計算するには環境変数`VASP_script`と`VASP_PP_PATH`を設定する
```bash
$ export VASP_SCRIPT=$HOME/vasp/run_vasp.py
$ export VASP_PP_PATH=$HOME/vasp/potentials/potpaw_PBE
```
* `VASP_SCRIPT`には以下のような内容を記述する
```python
import os
exitcode = os.system('vasp')
exitcode = os.system('mpirun -np 16 vasp') # 並列の場合
```
* `VASP_PP_NAME`はデフォルトとなる擬ポテンシャル(pseudo-potential)を設定する。シンボリックリンクでもOK

### DFT+U
* VASPのインプット(`INCAR`)で指定する場合のキーワード
  + `LDAU = [.TRUE.|.FALSE.]`: DFT+Uを使うかどうか
  + `LDAUTYPE = 2 (default)`: DFT+Uの手法選択
  + `LDAUL = [-1 (no on-site)|1 (=p)|2 (=d)|3 (=f)]`: どの軌道にUパラメーターを適用するか
  + `LDAUU`: on-site Coulombパラメーター
  + `LDAUJ`: on-site Exchangeパラメーター

* ASEでは`ldau_luj`dictで上記のLDAUL, LDAUU, LDAUJを設定する
* 以下はLa原子とO原子を含む系の計算の場合で、LaにはUパラメーターを指定し、O原子は補正しない
* 系に含まれるすべての原子に対してdictの要素を設定しないといけない(要確認)
```python
# DFT+Uパラメーターの設定
ldau = True
ldautype = 2
ldau_luj = {'La':{'L':2, 'U':3.0, 'J':0.0},
            'O':{'L':-1, 'U':0.0, 'J':0.0}}

# calculatorの定義
bulk.calc = Vasp(..., ldau=ldau, 
                      ldautype=ldautype,
                      ldau_luj=ldau_luj, ...)

# 計算の実行
bulk.get_potential_energy()

### Pseudo-potentialの選択
* 特殊なpseudo-potential(hard, softなど)を使いたい場合は`setups`で設定する
```python
calc = Vasp(xc='PBE', setups={'Li': '_sv'})
```

### calculatorを設定した後、パラメーターを変更する場合
1. setを用いる(おそらくこちらの方がよい)
```python
calc.set(prec="accurate", ediff=1E-5, ispin=2)
```
2. プライベート変数に直接代入
```python
calc.float_params["encut"] = 500.0
```

### スピン分極の計算
* スピン分極する場合は`VASP(..., ispin=2, ...)`とする
* INCARでMAGMOMを指定しない場合はデフォルトでは高スピン状態から始まる
    + `atoms.set_initial_magnetic_moments([1.0, 1.0])`で初期の磁気モーメントを原子ごとに指定
IT TIPSまとめてみた

### 概要
IT関連の用語解説のために調べた内容をまとめてみました。
選んだ用語に関連性は全然無いんですが、知っておくだけでも今後何かしらの役に立つかもしれません。

#### Windowsのコピー履歴
windowsキー + v でコピー履歴から選んでペーストできる（保持される履歴は25個まで）

#### プラットフォーム
ソフトウェアやシステムを動かすための基盤となる環境のこと。土台を指す言葉。

#### インスタンス
プログラムからメモリ上に実体化されたもの。
オブジェクト指向プログラミングにおいてクラスを元に実体化されたオブジェクトそのもの。

#### 水冷パソコン
水冷式コンピュータ。吸熱部分と放熱部分に冷却液を循環させて冷却する。
ファン（空冷）と比べて冷却性能が高く、静音性も高い。

#### USB
Universal Serial Bus（ユニバーサルシリアルバス）の略
キーボードやマウス、プリンタなどの接続方式として広く普及している。
１つの伝送路を最大127台の機器で共有することができる。
USBがなかった時代、マウスやキーボードといった機器ごとに独自の接続端子を採用しており、それぞれに対応したポート（端子穴）とそれに応じたケーブルを揃えなければならなかった。
それらの規格を統一し、ひとつのポートにさまざまな機器をつなげるようにした「ホットプラグ」という機能によって、PCの電源が入っていても端子を抜き差しできるようになった。

#### USB Type-A
USB端子の形状の一つ
1996年に策定された最初の規格（USB 1.0）
パソコン本体などコンピュータ側の端子として広く普及している
USB 3.0からは楕円に近い形状の「USB Type-C」が標準とされ、コンピュータ側、USB機器側共にType-Cへの移行が進みつつある。USB 3.2以降では最新規格での通信を行うにはType-Cが必須となり、Type-Aはマイクロ端子などと共に非対応となった
USB 3.1/3.0/2.0はすべて互換性があるので、同じType-Aの端子であればどれも接続でき、変換ケーブルを使えばほとんどの端子に対応します。
他のUSB規格だけでなく、ヘッドフォンのステレオ端子といった端子との互換性もあります。

### 参考にしたサイト
[IT用語辞典 e-Words](https://e-words.jp/)
[「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/index.html)

上記の用語解説を「#ココアのIT_TIPS」タグで毎週月曜日に弊社Xで投稿してます。
その他IT関連の小ネタやアニメ、ゲーム布教なども投稿してるので、ご興味のある方は是非フォロー、いいねをお願いします。
[ココア💜OCR公式エンジニア](https://x.com/obg_ocr)
SageMakerの使い方まとめ

# 概要

弥生R&D室のsiidaです。R&D室ではSageMakerを使用して機械学習 (ML) のプロジェクトを進めています。SageMakerはMLのための様々な機能が搭載されたサービスであり、データ分析からモデル訓練、ひいてはワークフローの構築まで、SageMakerの中で完結させることができます。

今回はこれまでに投稿してきた[SageMaker](https://aws.amazon.com/jp/sagemaker/)の使い方記事をまとめました。いわゆるAI/MLを活用したPoCの範囲で扱うSageMakerの基本的な機能を一通り網羅しています。

![sagemaker.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127680/995d5277-52e1-20d7-fb37-84807a3a6d32.png)


# 記事一覧

- [SageMakerのはじめかた](https://qiita.com/siida36/items/f6e4ba4a03b641fc5fea)
- [SageMaker Code Editorの紹介](https://qiita.com/siida36/items/81c0eb4a1cf7549379d4)
- [SageMakerでProcessingJobを使用するPythonラッパーの紹介](https://qiita.com/siida36/private/f8f263601fcd85a6bd9a)
- [SageMaker Studioの仮想マシンの容量を変更する方法](https://qiita.com/siida36/items/e1b9ddaacd260e901d00)
- [SageMaker ProcessingJobのCLIからのジョブ管理方法](https://qiita.com/siida36/items/77fa8cf53b42dc2dd63f)
- [ProcessingJobで使用可能なジョブ数を上げる方法](https://qiita.com/siida36/items/2d0326fb98b4a0ef7e44)

# ユースケース毎のガイド

## はじめてSageMakerを立ち上げる場合

[SageMakerのはじめかた](https://qiita.com/siida36/items/f6e4ba4a03b641fc5fea) を参照します。

もし、VSCode上のUIを使用したい場合は [SageMaker Code Editorの紹介](https://qiita.com/siida36/items/81c0eb4a1cf7549379d4) もオプションで参照してください。

## クイックにデータ分析を実施する場合

[SageMakerのはじめかた](https://qiita.com/siida36/items/f6e4ba4a03b641fc5fea) で作成した仮想マシンを使用すればNotebookから分析可能です。

データが大規模で仮想マシン上に配置できない場合には [SageMaker Studioの仮想マシンの容量を変更する方法](https://qiita.com/siida36/items/e1b9ddaacd260e901d00) を参照します。

より大規模なデータや前処理を実施する場合や、再現性のある分析プロセスを構築する必要がある場合は、後述のProcessingJobを使う記事をご覧ください。

## モデル作成・パイプライン構築など大規模な処理を実施する場合

[SageMakerでProcessingJobを使用するPythonラッパーの紹介](https://qiita.com/siida36/private/f8f263601fcd85a6bd9a) を参照してProcessingJobから処理を実行します。

またその際に [SageMaker ProcessingJobのCLIからのジョブ管理方法](https://qiita.com/siida36/items/77fa8cf53b42dc2dd63f) や [ProcessingJobで使用可能なジョブ数を上げる方法](https://qiita.com/siida36/items/2d0326fb98b4a0ef7e44) を参照することでジョブの管理に役立てることができます。

# まとめ

- SageMakerの基本的な機能について、ユースケース毎にまとめてみました
- AI/MLを使うPoCで必要となる、データ分析からモデル開発までのプロセスに対応しています
- より特定のケースに向けた機能については今後紹介する予定です

本記事は下記の記事と同じ内容です。 アクセス解析を目的としてマルチポストしています。

https://tech-blog.yayoi-kk.co.jp/entry/2024/09/30/110000

弥生では一緒に働く仲間を募集しています。 ぜひエントリーお待ちしております。

https://herp.careers/v1/yayoi/requisition-groups/2363876d-7695-46ea-9e6a-0bc64d11b6bc
早くkillしたいのでpecoで簡単killする。pecoが文字化けしたけど。

## 背景

プロセスをkillしたい時って早くkillしたいものですが、相変わらずpidの入力が面倒過ぎるし時間もかかるので、pecoでkillできるようにしてみました。
fzfでもいいのですが設定が凝り過ぎてしまうのでpecoにしました。

プロセス名を絞り込んでの起動もできるようにしたので便利です。

## 設定

.bashrcに記入します。
```bash
function peco-kill() {
  local PID PEC PRC
  [ $# = 0 ] && { PEC="peco"; PRC=""; } || { PEC="peco --query $1"; PRC=$1; }
  for PID in `ps aux | ${PEC} | awk '{ print $2 }'`; do
    kill ${PID}
    echo "killed: ${PRC} ${PID}"
  done
}

alias pk="peco-kill"
```

保存したらシェルを再起動します。
```bash
exec $SHELL -l
```


## 使い方

`pk`と入力すれば`ps aux`の結果がpecoで表示されます。
```bash
pk
```

例えば、`ps aux | grep node`みたいに`node`というワードで絞り込んで起動したい場合`pk node`とかすればできます。
```bash
pk node
```

## pecoが文字化けしたので
linuxmint22のパッケージ版だと、なんだか文字化けしたので、pecoのgithubからバイナリをダウンロードして、`peco`を`/usr/local/bin/`に入れたらちゃんと動きました。v0.5.11現在です。

https://github.com/peco/peco/releases

## おまけ。pecoのページ移動をPageDownキーで

ページ移動をついついPageDownキー・PageUpキーと指が反応してしまうので設定しました。
`~/.config/peco/config.json`に
以下を追記

```json
{
    ,
    "Keymap": {
        "Pgdn": "peco.ScrollPageDown",
        "Pgup": "peco.ScrollPageUp"
    }
}
```


現場からは以上です。
ありがとうございます。
Vert.xでリクエストチェーンを作る

javaでtcp proxy的なものを作りたくて今更ながらVert.xを触ってみた。
プロキシする前に（認証認可処理など）何かしらの処理を挟みたく、どうするか迷ったので解決策をメモする。

# Vert.xとは
Vert.xは非同期I/Oをベースにした高性能なリアクティブフレームワーク。
複数のプログラミング言語に対応し、スケーラブルな分散アプリケーション構築が可能。
クラスタリングや高可用性もサポートし、マイクロサービスやリアルタイムWebアプリに最適で、多様なエコシステムで拡張性も高く、分散システムにしている（と言われている）。

# Vert.xでリクエストチェーン
Vert.xではFuture/Promiseを使った非同期処理を書くことができる。
Futureをチェイニングすることが可能なので、以下のようにリクエストチェーンをかける。

```java
import io.vertx.core.Vertx;
import io.vertx.core.Promise;
import io.vertx.core.Future;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.NetClient;

public class RequestChainExample {
    
    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();

        // NetClient の作成
        NetClient client = vertx.createNetClient();

        // Step 1: リクエスト先のサーバーに接続
        connectToServer(client, "server-host", 8080)
            // Step 2: 1個目の処理実行
            .compose(socket -> firstRequest(socket))
            // Step 3: 2個目の処理実行
            .compose(socket -> secondRequest(socket, "Hello Server!"))
            // 全ての操作が成功したら
            .onSuccess(response -> {
                //　成功した場合の処理
                System.out.println(response);
            })
            // エラーがあればキャッチ
            .onFailure(err -> {
                System.out.println("Failed: " + err.getMessage());
            });
    }

    // サーバーへの接続 (Promise)
    private static Future<NetSocket> connectToServer(NetClient client, String host, int port) {
        Promise<NetSocket> promise = Promise.promise();
        client.connect(port, host, res -> {
            if (res.succeeded()) {
                System.out.println("Connected to Server");
                promise.complete(res.result());
            } else {
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }

    // 1個目の処理 (Promise)
    private static Future<NetSocket> firstRequest(NetSocket socket) {
        Promise<NetSocket> promise = Promise.promise();
        String message = "送信内容";
        socket.write(Buffer.buffer(message), writeRes -> {
            if (writeRes.succeeded()) {
                promise.complete(socket);
            } else {
                promise.fail(writeRes.cause());
            }
        });
        return promise.future();
    }

    // 2個目の処理 (Promise)
    private static Future<String> secondRequest(NetSocket socket, String message) {
        Promise<String> promise = Promise.promise();

        socket.write(Buffer.buffer(message), writeRes -> {
            if (writeRes.succeeded()) {
                socket.handler(buffer -> {
                    String response = buffer.toString();
                    promise.complete(response); // レスポンスを次に渡す
                });
            } else {
                promise.fail(writeRes.cause());
            }
        });
        return promise.future();
    }
}
```

ポイントは以下

- Promise と compose の使用
    - 各操作（接続、１つ目の処理、２つ目の処理）を Promise でラップし、それぞれの処理を compose を使ってシーケンシャルにチェーンしている
    - それぞれの操作が完了すると、次のステップに自動的に進む
- エラーハンドリング
    - 各 Future の操作に対して onFailure を設定し、問題が発生した場合に適切にエラーを処理する



便利！
(分析3)IBMiのライブラリ毎の種類別オブジェクト数をjupyterで集計

# ■概略
オープンソースエンジニア歴30年超の筆者が2023年からIBMiを学びだした学習記録です
IBMiのライブラリ毎の種類別オブジェクト数をjupyterで集計しました
SQL+pythonでループ+dataframeの使い方(合計追加と横持ち→縦持ち変換)です

# ■集計結果

<table border="1" style="border-collapse:collapse;width:800px">
<tr><td>OBJATTRIBUTE</td><td>CLP</td><td>DFU</td><td>DSPF</td><td>OTHER</td><td>PRTF</td><td>RPG</td><td>RPGLE</td><td>SAVF</td></tr>
<tr><td>BKNLIB</td><td>1444</td><td>207</td><td>1266</td><td>173</td><td>265</td><td>2495</td><td>228</td><td>0</td></tr>
<tr><td>BKNLIBF</td><td>0</td><td>0</td><td>0</td><td>60</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>TOTAL</td><td>2469</td><td>365</td><td>2136</td><td>360</td><td>414</td><td>4525</td><td>256</td><td>1</td></tr>
</table>
<BR>…続く(画面に入らないので左右に分割し上下に並べた)<BR>
 
<table border="1" style="border-collapse:collapse;width:800px">
<tr><td>OBJATTRIBUTE</td><td>LF</td><td>PF</td><td>QRY</td><td>TOTAL</td></tr>
<tr><td>BKNLIB</td><td>0</td><td>56</td><td>252</td><td>6386</td></tr>
<tr><td>BKNLIBF</td><td>816</td><td>1046</td><td>5</td><td>1927</td></tr>
<tr><td>TOTAL</td><td>3710</td><td>4986</td><td>650</td><td>19872</td></tr>
</table>

# ■集計コード
※jupyterのインストール、接続などの共通関数は
　[(分析1)jupyterでSQL設計とデータ分析](https://qiita.com/takami_embomajp/items/225a5f45c988a0dcd87d)に掲載している
　使用しているSQLは上記の「オブジェクト名取得(DSPFD相当)」
```
# DB接続
conn = connect_dev()

df = pd.DataFrame()
LIBL = ['BKNLIB', 'BKNLIBF'] # 集計するライブラリの配列を指定する
for LIB in LIBL:
    # (分析1)...の「オブジェクト名取得(DSPFD相当)」のSQLでライブラリ名を
    # pythonのループで指定している
    query = """
    SELECT '{0}' as LIBID,OBJATTRIBUTE,count(*) as CNT
      FROM TABLE(QSYS2.OBJECT_STATISTICS('{0}','*ALL'))
     group by OBJATTRIBUTE
     order by OBJATTRIBUTE
    """.format(LIB)
    df_tmp = pd.read_sql(sql=query, con=conn)
    df_tmp = df_tmp.replace('', 'OTHER') # 空白はOTHERにする
    # 1ライブラリにつき種類別行数の集計を結合する
    df = pd.concat([df, df_tmp], ignore_index=True)
#display(df)

# 縦持ちを横持ちにする
pivot_df = df.pivot_table('CNT', index=['LIBID'], columns=['OBJATTRIBUTE'], aggfunc='sum')
pivot_df = pivot_df.fillna(0)   # N/Aを0にする
pivot_df = pivot_df.astype(int) # 整数にする
pivot_df['TOTAL'] = pivot_df.sum(axis = 1,numeric_only=True) # 各行の合計
# 各列の合計
total_df = pivot_df.sum(axis = 0).to_frame().T
total_df.index=["TOTAL"]
pivot_df = pd.concat([pivot_df, total_df])

dt_now = datetime.datetime.now().strftime('%Y%m%d%H')
print("■as400dev({0})".format(dt_now))
display(pivot_df)

# CSVに出力する
pivot_df.to_csv('DSPOBJD@AS400DEV_{0}.csv'.format(dt_now))
```

◯縦持ちを横持ち変換(pivot)
pivot_table前のdataframeは以下の形になっている
BKNLIBで1行、BKNLIBFで1行にまとめたい=縦持ちを横持ちに変換したい
pivot_tableで変換を行う。詳しくはpandas.dataframeのpivot_tableを調べてください

<table border="1" style="border-collapse:collapse;width:800px">
<tr><td></td><td>LIBID</td><td>OBJATTRIBUTE</td><td>CNT</td></tr>
<tr><td>0</td><td>BKNLIB</td><td>OTHER</td><td>173</td></tr>
<tr><td>1</td><td>BKNLIB</td><td>CLP</td><td>1444</td></tr>
<tr><td>2</td><td>BKNLIB</td><td>DFU</td><td>207</td></tr>
<tr><td>3</td><td>BKNLIB</td><td>DSPF</td><td>1266</td></tr>
<tr><td colspan=4>…</td></tr>
</table>
【時間がなくても読んでおけ】業務に役立った駆け出しエンジニア向けおすすめ書籍

# 本記事について

1年間で特に業務に役立った書籍を紹介します。

短期間で多くの本を読むのは難しいため、実際に読んで即実践できそうだと感じたものを厳選しました。

# おすすめ書籍

下記の2点をおすすめします。

- [リーダブルコード](https://www.amazon.co.jp/dp/4873115655)
- [世界一流エンジニアの思考法](https://www.amazon.co.jp/%E4%B8%96%E7%95%8C%E4%B8%80%E6%B5%81%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E6%80%9D%E8%80%83%E6%B3%95-%E7%89%9B%E5%B0%BE-%E5%89%9B/dp/4163917683)

設計や理論など様々な選択肢がありますが、業務に即実践でき、継続することで大きな成長が期待できると感じました。

## リーダブルコード

著：Dustin Boswell, Trevor Foucher

### ポイント

- コードの読みやすさを重視するテクニックが紹介されている
- 複雑になりがちなロジックを、いかに読みやすく改善できるかを具体例を用いて解説
- すべてのエンジニアにとって、超重要な基礎を学べる

### 実践と効果

- 命名に対して違和感を持てるようになり、命名に関するコードレビューが自然とできるようになった
- 入社当初から1年経った今でも重要だと感じる点が多く、繰り返し読み返している

## 世界一流エンジニアの思考法

著: 牛尾 剛

### ポイント

- 米マイクロソフトの現役ソフトウェアエンジニアが、優秀なエンジニアたちから学んだ一流の思考法を紹介
- 日本人が当たり前と感じていることが、実は生産性を下げる原因であることも

### 実践と効果

- コードの理解に時間をかけることで質問量が増え、理解度が上がった
- 理解が深まると仕事の完了スピードが格段に向上
- 逆に、コード理解をおろそかにした期間は、生産性が大幅に低下した

# 最後に

書籍を読み切って満足するのではなく、得た情報をどう活用するかを考え、実際に実践していくことが大切です。
Databricks AI/BIダッシュボードを外部アプリケーションに埋め込めるようになりました！

こちらの2024年9月11日のアップデートです。

https://docs.databricks.com/ja/sql/release-notes/index.htm

> AI/BI ダッシュボードを Databricks の外部のアプリケーションに iframe として埋め込むことができるようになりました。 [「ダッシュボードの埋め込み」](https://docs.databricks.com/ja/dashboards/share.html#embed-a-dashboard)を参照してください。

ダッシュボードの画面で**共有**ボタンを押します。画面下に**Embed dashboard**が表示されています。こちらをクリックします。
![Screenshot 2024-09-27 at 10.37.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/e864e111-a054-83fa-b2fd-14d7d84e8c22.png)

`iframe`のコードが表示されます。この際に注意するのは、**どのサイトへの埋め込みを許可するのか**ということです。以下の例では、`*.hatenablog.com`に埋め込みを許可しています。この設定はワークスペースレベルで行うことができます。
![Screenshot 2024-09-27 at 10.37.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/8afb14af-a46c-58b7-8350-5f7c8903726a.png)

上の画面に表示されている**ワークスペース設定**のリンクをクリックします。
![Screenshot 2024-09-27 at 10.43.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/01494429-9268-1b87-3c21-927b2af641cd.png)

こちらでは以下を選択できます。

- 許可
- 承認済みドメインを許可
- 拒否

**承認済みドメインを許可**を選択して、承認済みのドメインを登録することが推奨となります。詳細は[こちら](https://docs.databricks.com/ja/dashboards/admin-guide.html#manage-embed)をご覧ください。
![Screenshot 2024-09-27 at 10.45.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/2e4a4464-3dbc-65ae-0b41-3f9421ee0de3.png)

設定が完了したら、上のiframeを記述して外部アプリケーションに組み込みます。アクセスするとDatabricksへのログインを求められます。
![Screenshot 2024-09-27 at 10.18.38.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/bd4e7985-5e2a-0558-4cfe-d841135c7105.jpeg)

ログインが完了すると、ダッシュボードが表示されるようになります！
![Screenshot 2024-09-27 at 10.32.15.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/ab4eaa06-dfc3-2f0e-4707-5e5b4c331557.jpeg)

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
【Laravel】X-Forwarded-ForからIPアドレスを取得する方法！

泉（[@izumin_0401](https://twitter.com/izumin_0401)）です。

今回は、LaravelでX-Forwarded-ForからIPアドレスを取得する方法を解説するンゴ。

# ブログ記事はこちら

https://traveler0401.com/laravel-x-forwarded-for/

# 【Laravel】X-Forwarded-ForからIPアドレスを取得する方法

```php
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use RSResponse;

class IpAddress
{
    public function handle(Request $request, Closure $next)
    {
        $forwardedFor = $request->header('X-Forwarded-For');

        if ($forwardedFor) {
            // X-Forwarded-Forはカンマ区切りで複数のIPが送信される可能性があるため、最初のIPを取得する
            $ips = explode(',', $forwardedFor);
            $ip  = trim($ips[0]);
        }

        return $next($request);
    }
}
```
今回はミドルウェアで実装してみた。

ベリーイージーね。

# まとめ
意外と簡単でしたわ。ガハハ。

ではまた。

# 最後に
暇つぶしに[Twitter](https://twitter.com/izumin_0401)と[ブログ](https://traveler0401.com/)もやってるので見てね。
プロンプトの提案

このプロンプトは、状況説明、目標設定、段階的なアクション、結果形式、カスタマイズ、参照資料の提供という構成で作成されており、エラーを最小限に抑えつつ、LLMの出力を最適化します。

## 従来のプロンプト作成における課題

初めてプロンプトを作成する際、以下のような問題がよく発生します。

- **不明瞭な指示**: 曖昧な表現やAIに任せるような指示。
- **文脈の不足**: LLMが理解しやすい具体的な状況や対象が欠けている。
- **繰り返しの修正**: 明確なガイドラインがないため、プロンプトの修正が頻発。

これらの課題を解決するために、「SMART+ER プロンプトテンプレート」を提案します。

## プロンプトテンプレートの構成

### 1. 長期的な目的の説明（状況の俯瞰） 

まずは、現在の状況や背景を説明しましょう。

```markdown
## SITUATION
我が社は新製品を発売予定です。
```

### 2. 目標設定

次に、何を達成したいか、目標を明確にします。

```markdown
## MISSION
この製品で20代女性顧客をターゲットにしたい。
```

### 3. アクションの段階的実行

AIが実行するべきステップを具体的に示します。1つのタスクを1ステップで実行し、完了後に次のステップに進むかどうかを確認します。

**”重要: 各STEPは1つずつ実行し、完了後に次のステップに進むかどうかを確認してください。”** という文言を追加。

```markdown
## ACTION STEPS
"重要: 以下の各STEPは1つずつ実行し、完了後に次のステップに進むかどうかを必ずユーザーに確認してください。"
1. 20代女性顧客の関心を分析してください。
2. 分析結果に基づいて、マーケティング戦略を3つ提案してください。

```

### 4. 結果の形式

結果物の形式を指定します。

```markdown
## RESULT FORMAT
提案書形式でA4サイズ1枚分にまとめてください。
```

### 5. カスタマイズ

必要に応じて、結果の表現やスタイルをカスタマイズします。

```markdown
## CUSTOMIZE
- 分析結果は棒グラフで表示してください。
- すべての内容は中学2年生レベルで書いてください。
- すべての内容は日本語で作成してください。
- 内容に適切な絵文字を追加してください。
- 親しみやすく明るいトーンで書いてください。
```

### 6. 参照資料

必要に応じて、AIが参考にできる資料を提供します。

```markdown
## EXAMPLES
- 添付した「成功したマーケティングレポート.pdf」を参考にしてください。
- 添付したGoogleドライブリンクの「過去四半期の販売レポート.txt」を参照してください。
- 添付したサンプルのメールファイルを参考にしてください。
```

### 7. 資料の提供

AIが結果を生成するために必要なリソースを提供します。

```markdown
## RESOURCES
- 添付した「販売記録ファイル.txt」を使用してください。
- 添付したGoogleドライブリンクの「00タブの00列」のデータを利用してください。  
- ファイル画像: 「画像_ファイル名.jpg」  
- ファイル形式: 「エクセル_ファイル名.xlsx」  
- 会議録音ファイル: 「録音_ファイル名.mp3」  
- 動画ファイル: 「動画_ファイル名.mp4」  
- ウェブ検索で最新の市場動向を調査してください。  
- ウェブURL: 「https://example.com/page/1」  
```

## 全体プロンプトテンプレート（CTRL+C, Vにしてお使いください。）


```markdown

## SITUATION
我が社は新製品を発売予定です。

## MISSION
この製品で20代女性顧客をターゲットにしたい。

## ACTION STEPS
"重要: 以下の各STEPは1つずつ実行し、完了後に次のステップに進むかどうかを必ずユーザーに確認してください。"
1. 20代女性顧客の関心を分析してください。
2. 分析結果に基づいて、マーケティング戦略を3つ提案してください。

## RESULT FORMAT
提案書形式でA4サイズ1枚分にまとめてください。

## CUSTOMIZE
- 分析結果は棒グラフで表示してください。
- すべての内容は中学2年生レベルで書いてください。
- すべての内容は日本語で作成してください。
- 内容に適切な絵文字を追加してください。
- 親しみやすく明るいトーンで書いてください。

## EXAMPLES
- 添付した「成功したマーケティングレポート.pdf」を参考にしてください。
- 添付したGoogleドライブリンクの「過去四半期の販売レポート.txt」を参照してください。
- 添付したサンプルのメールファイルを参考にしてください。

## RESOURCES
- 添付した「販売記録ファイル.txt」を使用してください。
- 添付したGoogleドライブリンクの「00タブの00列」のデータを利用してください。  
- ファイル画像: 「画像_ファイル名.jpg」  
- ファイル形式: 「エクセル_ファイル名.xlsx」  
- 会議録音ファイル: 「録音_ファイル名.mp3」  
- 動画ファイル: 「動画_ファイル名.mp4」  
- ウェブ検索で最新の市場動向を調査してください。  
- ウェブURL: 「https://example.com/page/1」  
```

## ChatGPTに公開しました。

https://chatgpt.com/share/66fc94ff-6024-8005-a73a-ba0e934e882b

**最初に「プロンプトテンプレート」をクリックしてください。**
表示された「プロンプトテンプレート」の文章を、自分の状況に合わせて書き換えてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/f1e9b611-0688-8318-e81c-7c929ab2e91c.png)
リモナビ：永続的な無料利用！

# リモナビは期間制限なく「無料利用」が可能
プライベートネット間をL4 (TCP|UDP) 接続することができる <INS>RemoNavi SaaS</INS> は**無料で利用することができます**。

無料だと接続先は１つ、月の通信量は [100] Mbyte の制限がありますが、
 - ローカル環境のデータベースにアクセスしたり
 - ローカル環境のサーバに ssh | sftp 接続したり、
 - fluentd でローカル環境のログを別のローカル環境に転送したり
 - もちろんリモートデスクトップだってできます（RDPは通信量が多いので上限に達するのは早いですが）

なんてことは朝飯前です。

**それもずっと無料のまま使い続けることができるんです！**

# 無料登録はこちらから
[RemoNavi サブスク](https://remonavi.com/?pos=subscription)

上記リンクにアクセスしたら、下図の登録をするだけ。

<img width="1240px" src="https://remonavi.com/img/remonavi_free.png">

# リモナビを使うことの意義
プライベートネット間を接続できることはもちろんですが、それ以外にも意義があります。

- RemoNavi SaaS を使うと通信技術を習得できます。
  - Socket通信プログラムで TCP通信はできるけど、インターネットとの関係は？
  - VPNは [L2] で、RemoNavi SaaS は [L4]　って何？
  - 脱VPNって何？
<br>

- RemoNavi SaaS を使うことによって、さまざまな通信技術を習得できます。
[RemoNavi SaaS を使った通信 (Qiita投稿記事)](https://remonavi.com/?pos=saas_doc)
  - データベース接続も TCP/IP で実現している
  - 映像転送通信は実はとても複雑なのに、単純化する方法がある
  - fluentd 転送の中継も TCP/IP で実現することができる
  - リモートデスクトップ接続も TCP/IP で実現している

　などなど。 実はよく知られた FTP PASV 通信なんかも簡単にはリモート接続を実現できなかったりします。 FTPはなかなかに面倒なので、sftp の利用をお勧めします。
 
 　RemoNavi は SaaSで実現するリモート接続のインフラなので、接続できるのは L4 (tcp|udp 5th element P2P接続) です。それゆえ L4 コネクション を複数利用するような複雑なプロトコルは、それらを技術的に理解して リモート接続を実現する必要があるのです。（L6 TLS, L7 http|https もできますが）
  
　リモナビは通信と通信セキュリティのスペシャリスト集団によって開発されたものです。　ただ海外ツールを使うのではなく、確かな通信技術を習得して、**世界に先駆けたプライベートネット間接続をともに実現していきましょう！**
phpのオブジェクト指向の整理

# 始めに
オブジェクト指向はクリーンアーキテクチャするうえでは持っておきたい知識だと思ってる。

今まで以下のような書籍を読んだが、これから会社都合でガッツリlaravel書くことになりそうなのでphpならどんなふうに考えるのかの整理のために書いていく

# 今まで読んだオブ脳関係

(多分絶版だけど。アフィリンクじゃないよ！)
メルカリにも中古は有るよ。
### オブジェクト指向設計実践ガイド（Ruby）
Ruby触るならイメージ湧きやすと思う。

https://www.amazon.co.jp/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E8%A8%AD%E8%A8%88%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-Ruby%E3%81%A7%E3%82%8F%E3%81%8B%E3%82%8B-%E9%80%B2%E5%8C%96%E3%81%97%E3%81%A4%E3%81%A5%E3%81%91%E3%82%8B%E6%9F%94%E8%BB%9F%E3%81%AA%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E8%82%B2%E3%81%A6%E6%96%B9-Sandi-Metz/dp/477418361X

### オブジェクト脳の作り方
最初に読むべきだと思ってる。内容はJavaだが概念がマジでわかりやすい

https://www.shoeisha.co.jp/book/detail/9784798104188

# 内容
そもそもオブジェクト指向とは・・・
ー＞平たく言うと役割分担

- カプセル化（役割分担）
- 継承（引き継ぎ）
- ポリモーフィズム（多様化）

phpに関するデザインパターンは以下のページがめちゃくちゃ勉強になる。感謝。。。

https://shimooka.hateblo.jp/search?q=%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3

# メモ
クラスのアクセス修飾子
**private**・・・外からアクセスできない
**protected**・・・自分と継承先のみ
**public**・・・誰でもウェルカム

# 継承
書き方

```php
//親クラス
class BaseProduct {
  //変数・関数
  public function echoHoge(){
  echo 'ほげほげ';
  }
}

//子クラス
class Product extends BaseProduct {
  $instance->echoHoge();
}
```
親クラスの内容を継承。子クラスに同じ関数がある場合。子クラス優先。オーバーライドは使う場面が思いつかん。
おまけでfinal pubilic~~とするとそれ以上継承できない

# 補足（抽象クラス：abstract, interface）

```php
abstract class HogeAbstract{

  abstract public function getHoge(){
    echo '抽象クラス';
  }
}
```
抽象クラスをつを使うとそのメソッドを必ず使わなきゃいけなくなる
ー＞書いてるけど忘れてるメソッドの無駄防止
interfaceは複数継承できる。

```php
class Product implements ProductInterface, NewInterface{
  public function getHoge();
}
```

**但しinterfaceは中身書かないよ！**
XIAO ESP32S3ボードでLEDを点滅させるプロセス

XIAO ESP32S3ボードでLEDを点滅させるプロセスと、遭遇したエラーの解決方法をまとめます。


```markdown
# XIAO ESP32S3 LED点滅プロジェクト

このプロジェクトでは、Seeed Studio XIAO ESP32S3ボードを使用してLEDを点滅させる方法を説明します。

## 準備

1. XIAO ESP32S3ボード
2. USB Type-Cケーブル（データ転送対応）
3. Arduino CLIがインストールされたPC

## 手順

1. XIAO ESP32S3ボードをUSB Type-Cケーブルでコンピュータに接続します。

2. 以下のコードを`XIAO_ESP32S3_Blink.ino`ファイルとして保存します：

```cpp
const int LED_PIN = 21;  // XIAO ESP32S3の内蔵LED

void setup() {
  Serial.begin(115200);
  pinMode(LED_PIN, OUTPUT);
}

void loop() {
  Serial.println("LED ON");
  digitalWrite(LED_PIN, HIGH);
  delay(1000);
  Serial.println("LED OFF");
  digitalWrite(LED_PIN, LOW);
  delay(1000);
}
```

3. Arduino CLIを使用してコードをコンパイルします：

```
arduino-cli compile --fqbn esp32:esp32:esp32s3 XIAO_ESP32S3_Blink
```

4. コンパイルしたコードをボードにアップロードします：

```
arduino-cli upload -p /dev/ttyACM0 --fqbn esp32:esp32:esp32s3 XIAO_ESP32S3_Blink
```

5. シリアルモニターを開いて動作を確認します：

```
arduino-cli monitor -p /dev/ttyACM0 -c baudrate=115200
```

## トラブルシューティング

1. **コンパイルエラー**: arduino-cliが正しくインストールされていることを確認してください。必要に応じて、ESP32ボードパッケージを更新します：

```
arduino-cli core update-index
arduino-cli core install esp32:esp32
```

2. **アップロードエラー**: 
   - USBケーブルがデータ転送に対応していることを確認します。
   - 別のUSBポートを試してみます。
   - ボードが正しく認識されているか確認します：`arduino-cli board list`

3. **LEDが点滅しない**:
   - ピン番号が正しいか確認します（XIAO ESP32S3では通常21番ピンがLEDに接続されています）。
   - ボードの電源が入っているか確認します。

4. **シリアル出力が見えない**:
   - 正しいボーレートを使用していることを確認します（115200 bps）。
   - USBドライバが正しくインストールされているか確認します。

## 注意点

- XIAO ESP32S3ボードは、一般的なESP32S3ボードとは若干設定が異なる場合があります。必ず`esp32:esp32:esp32s3`のFQBNを使用してください。
- ボードによっては、アップロード時にブートローダーモードに手動で入る必要がある場合があります。その場合は、BOOTボタンを押しながらRESETボタンを押し、その後BOOTボタンを離します。

以上の手順とトラブルシューティングを行うことで、XIAO ESP32S3ボードでLEDを正常に点滅させることができます。エラーが発生した場合は、エラーメッセージを注意深く読み、適切な対処を行ってください。
Null合体演算子について(??)

# Null合体演算子ってなーに
論理演算子の一つで、左辺が`null`または`undefined`の場合には、右辺の値を返して、そうでない場合には左辺の値を返すものです。
ES11で導入されたようです。
```javascript
const hoge = null ?? "I am a person";
console.log(hoge);// I am a personが出力されます

const hogeHoge = "ok" ?? "I am a person";
console.log(hogeHoge);// ok が出力されます
```
こんな感じになります。

# どんな場面で使えるの？
オプショナルチェーンと同時に用いることでより安全な書き方が可能になります。
（オプショナルチェーンに関しては私が書かせていただいたこちらの記事も同時にご参照ください🙇）

https://qiita.com/dashubei/items/9cdbfd598a10f4667a35

オプショナルチェーンでは、参照したプロパティが存在しない場合エラーではなく、`undefined`が入るのですが、さらにNull合体演算子を組み合わせることで、`null`や`undefined`のときに代替する値をいれることができます！

```javascript
const family = {};
const motherAge = family?.mother?.age ?? "〇〇";
console.log(`${motherAge}歳`);// 〇〇歳と出力される
```
こんな感じですね！

従来も別の書き方を用いて、同じような挙動のものは書けたと思いますが、オプショナルチェーンのときと同様、こちらのほうがスッキリと書くことができますね。

# || （論理OR演算子）との違いについて
似たような挙動をするものに論理OR演算子があります。これは、左側が`falthy`の場合に右側を返すというものです。Null合体演算子と重複するような挙動でもありますが、左側が`falthy`というのは`null`や`undefined`の他にも、`false`,`0`,`''`,`Nan`などがあります。

Null合体演算子はデフォルト値をセットしたい時に使うと良いようです。

```javascript
const family = {
    baby: {
        age: 0,
        ...
    },
    ...
};

const babyAge = family?.baby?.age ?? "〇〇";
console.log(`${babyAge}歳`); // 0歳

const babyAge2 = family?.baby?.age || "〇〇";
console.log(`${babyAgew}歳`); // 〇〇歳
```

このように出力の違いが出てきます。これは実装の際に上手く活用すると良いです！（~~私は上手く活用できそうではありません笑~~）
モバイルアプリで画面フローを使って検索を少し便利にする


取引先の関連リストに取引先責任者（弊社では名刺と呼んでいます）が当然あるのですが、モバイルアプリだと折りたたまれているんですよね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/6ac6068d-422d-9790-ce3b-d596772adbaa.png)

関連をクリックしても、もう一回クリックしないとレコードが表示されません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/084b5f79-815d-be6d-6ee3-a0fefc008250.png)

コンパクトレイアウトの順番を変えたら携帯の電話番号は出せそうですが...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/423b1692-eb9c-4e7d-9d29-4308ac8b8072.png)


そこで、画面フローを作って名刺レコードをテーブルに表示させてみることにします。
１クリックは減る。
上の一番左の「名刺」ボタンをクリックすれば、以下のように表示できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/0d4e8d7e-901b-fc45-b6a4-80afedfb4376.png)

以下のようにretURLを指定することで、完了ボタンをクリックすると元の取引先画面に戻ることができます。

```
/flow/ContactLists?recordId={!Account.Id}&retURL={!Account.Id}
```

今回は表示されている取引先責任者の名前をクリックすると取引先責任者の詳細ページに飛ぶようにしたかったので、以下のような数式項目を作って表示させています。



```
HYPERLINK(LEFT($Api.Enterprise_Server_URL_610 , FIND('/services', $Api.Enterprise_Server_URL_610)) & "/lightning/r/Contact/"& Id & "/view",   LastName &  FirstName )
```

一瞬カスタムコンポーネントでも組もうかと思いましたが画面フローを使ってみました。案外使えるかもしれません。
PowerApps コレクションの変換1

# 元データ

Parent_table
|id |product_name|
|---|---|
|1  |商品A|
|2  |商品B|

Child_table
|id |product_id |year |sales |
|---|---|---|---|
|1   |1|2024  |100|
|2   |1           |2025  |200
|3   |1           |2026  |300
|4   |2           |2024  |10
|5   |2           |2025  |20
|6   |2           |2026  |30

# 目標
target_col
|id |product_name|2024|2025|2026|sale_id_1|sale_id_2|sale_id_3
|---|---|---|---|---|---|---|---|
|1  |商品A|100|200|300|1|2|3
|2  |商品B|10|20|30|4|5|6

# 方法
```
//Child_tableをグループ化にする
ClearCollect(
    Parent_table_group_col,
        AddColumns(
            Parent_table As a,
            group,
            ShowColumns(
                Filter(
                    Child_table As b,
                    a.id = b.product_id
                ),
                id As sale_id,
                year,
                sales
            )
        )
);

ClearCollect(
    target_col,
    ForAll(Parent_table_group_col,
        {
       id :  id,
        product_name : product_name,
        2024 :  First(Filter(
                    group As b,
                     b.year = 2024
                )).sales,
        2025 :  First(Filter(
                    group As b,
                     b.year = 2025
                )).sales,
        2026 :  First(Filter(
                    group As b,
                     b.year = 2026
                )).sales,
        sale_id_1 :  First(Filter(
                    group As b,
                     b.year = 2024
                )).sale_id,
        sale_id_2 :  First(Filter(
                    group As b,
                     b.year = 2025
                )).sale_id,
        sale_id_3 :  First(Filter(
                    group As b,
                     b.year = 2026
                )).sale_id
        }
    )
);
野良 ports を集計に参加させない為のスクリプト

[sysutils/bsdstats](https://www.freshports.org/sysutils/bsdstats/) ってのが、web インターフェイスが死んでるものの裏では[統計が出来て](https://www.bsdstats.org/pc-bsd/ports.php?)そうな🤔
[ココ](https://www.bsdstats.org/netbsd/ports.php)とかね。

で、今更感 MAX ではあるが、その集計に参加させたくない野良 ports を一覧にする。
[過去記事](https://qiita.com/je3kmz/items/c55cd2c88d1045be1e9d)に ports のインスコ方法書いてて、ソコにも激簡単に書いとるが、1mm 程度深堀してみた🎉
```shell:ご本尊
#!/bin/sh
TEMPFILE=`mktemp -q ${TMP:-/tmp}/\`basename $0_$$\`.XXXXXX`
PORTSLIST=/usr/local/etc/bsdstats.conf
pkg info -oq > $TEMPFILE
for a in `pkg version -vo | grep "?" | awk '{print$1}'`
do
sed -i"" -e "s:"${a}"::g" $TEMPFILE
done
sort $TEMPFILE > $PORTSLIST
unlink $TEMPFILE
exit
```
ココからはコマンド事にウッスラと解説してみた😁
```text:現在インスコされちょる一覧を吐き出す
pkg version -v
```
```text:参考：フォーマット(実行結果とも言う)
py311-wheel-0.43.0                 <   needs updating (index has 0.44.0)
python311-3.11.9_1                 =   up-to-date with index
readline-8.2.10                    >   succeeds index (index has 8.2.:[.1]})
rec_radiko-20231031                ?   orphaned: multimedia/rec_radiko
```
名前\`\<sp>'ヴァージョンの差異とskeletonの有無\`\<sp>'概要\`\<sp>'オリジナルパッケージ名
```text:ヴァージョンの差異を判定材料として grep で摘まむ
grep "?"
```
その後、\<sp>で区切られて出力されていて4セル目にオリジナル名が吐き出されておるけん awk でソコだけ抽出する
```text
awk '{print$4}'
```
後は、好みの問題w
```text:順送り整頓
sort
```
結果を追記状態で/usr/local/etc/bsdstats.confへ渡して終了
```text
>> /usr/local/etc/bsdstats.conf
```

man
[PKG(8)](http://koganemaru.co.jp/cgi-bin/mroff.cgi?subdir=man&lc=1&cmd=&man=pkg&dir=jpman-15.0.2%2Fman&sect=0)
[GREP(1)](http://koganemaru.co.jp/cgi-bin/mroff.cgi?subdir=man&lc=1&cmd=&man=grep&dir=jpman-15.0.2%2Fman&sect=0)
[AWK(1)](http://koganemaru.co.jp/cgi-bin/mroff.cgi?subdir=man&lc=1&cmd=&man=awk&dir=jpman-15.0.2%2Fman&sect=0)
[SORT(1)](http://koganemaru.co.jp/cgi-bin/mroff.cgi?subdir=man&lc=1&cmd=&man=sort&dir=jpman-15.0.2%2Fman&sect=0)
[MKTEMP(1)](http://koganemaru.co.jp/cgi-bin/mroff.cgi?subdir=man&lc=1&cmd=&man=mktemp&dir=jpman-15.0.2%2Fman&sect=0)
[BASENAME(1)](http://koganemaru.co.jp/cgi-bin/mroff.cgi?subdir=man&lc=1&cmd=&man=basename&dir=jpman-15.0.2%2Fman&sect=0)
[RM(1),UNLINK(1)](http://koganemaru.co.jp/cgi-bin/mroff.cgi?subdir=man&lc=1&cmd=&man=unlink&dir=jpman-15.0.2%2Fman&sect=0)

最後に
今のトレンドは [sysutils/hw-probe](https://www.freshports.org/sysutils/hw-probe) なんじゃろなw
1日5分から始める言語化

## 本の情報
**タイトル**
瞬時に「言語化できる人」が、うまくいく。

**著者**
荒木 俊哉

## 本の内容
* 言語化とは
言語化とは、頭の中の感覚や概念を言葉にすること。
言語化により、自分独自の考えや経験を示せるようになることが重要。
→相手に新しい気付きや視点を与えることになり、評価につながるため

* 言語化できるようになるには
人は、日々多くのことを感じているが、それを無意識下に追いやってしまっている。
この無意識下にあるものを意識下に持ってきて、何を感じたのかを言葉で理解することが必要。
→これを行うためには、「とりあえず書き出してみる」ことが有効な手段となる。
書きだす際には言葉にしないといけないので、強制的に感覚や概念を言葉で示すことになる。
更に、書きだした言葉が引き金となり、更なる感覚や概念が連想されて次の言語化につながる。

* 書き出す訓練
1つの質問を用意し、それに対する「思考(思ったこと)」と「理由(そう思った理由)」を実際に書いてみる。
この際、意識すべき点として以下がある。
・とりあえず書く：正解不正解がある作業ではない。自身のトレーニングなので、浮かんできたことを素直に書いてみることが必要。
・制限時間を設定する：実生活では、即座に意見を求められる場面が多い。トレーニングでも長い時間をかけて考えるのではなく、2分程度で集中して考えてみるのが良い。
・自分の経験を振り返る：言語化するとっかかりや自分の言葉で語るための情報として、自分の経験が重要になる。経験した出来事とその時感じたことを振り返るようにすると、言語化しやすくなる。

言語化の目標は、相手が理解できる言葉で共有できること。
普段から言語化の練習をするための問いを立て続け、相手を思い浮かべながら訓練することで、確実に言語化力を伸ばしていくことができる。

## ためになった点
* トレーニング
具体的かつ詳細にトレーニングに関する内容が記載されていた。
加えて、問いが立てられなかった際の例題も多数掲載されており、続けやすいトレーニングという点に強い意識が向けられている内容だった。
これなら始められるという印象を持ったので、まずは一度取り組んでみたい。

* 経験の重要性
自身が経験してきたことに、言語化のきっかけや新たな視点があるという記載があった。
自分には語れるような経験がないと思い込んでしまっていたので、新たな視点を得られた内容だった。
経験を振り返ったことがあまりなかったので、その点を含めながらトレーニングを行うようにしたい。

## まとめ
言語化の概念に加えて、どのように言語化の力を付けるか に重点を置いて記載されている内容でした。
最初の一歩が踏み出せないということが多々あったので、その点に関してもフォローされていて、自分に向けられていると感じる箇所もありました。
まずは、紙とペンを手に持って始めてみたいと思います。
ありがとうございました。
無料開発者リソースマインドマップ | ツール、サービス、プラットフォーム

オンラインでマインドマップを見るには：[https://free-for-dev.edgeone.app](https://free-for-dev.edgeone.app/)

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3813484/f022c392-8671-444a-e994-23bd593b7b4c.png)


この開発者の無料リソースマインドマッププロジェクトは、githubプロジェクトから派生したものです：https://github.com/ripienaar/free-for-dev

このプロジェクトは、SaaS、PaaS、IaaSなどを含む、無料のクラウドサービスを提供する多数のリソースを示しており、企業や独立した開発者が低コストまたはゼロコストで迅速に自分の製品を立ち上げるのに役立ちます。
RSpecでのテストでカバレッジを確認する方法

# はじめに

こんにちは！
社会人一年目の石川です。
記事をご覧いただきありがとうございます。

本記事では、RSpecでテストカバレッジを出力する方法についてまとめます。

# 目次
1. [カバレッジとは？](#カバレッジとは)
1. [ツールについて](#ツールについて)
1. [導入手順](#導入手順)
4. [最後に](#最後に)


# カバレッジとは

テストカバレッジは、コードのうちどれだけがテストされているかを割合で表したものです。これにより、未テストの箇所を特定できるため、テストがコード全体をどの程度カバーしているかを確認できます。


# ツールについて
カバレッジを測定するための代表的パッケージが`SimpleCov`です。
他にも、以下のようなツールがあります。
##### Coveralls
オンラインでチーム共有をサポートし、継続的インテグレーション（CI）と連携しやすい点が強みです。
##### Codecov
詳細なグラフやレポートを提供し、特にCI/CDパイプラインに強力に統合されます。



# 導入手順
今回は`simplecov`の導入手順についてまとめます。
### パッケージのインストール
Gemファイルに以下の行を追加し、`bundle install`を実行します。
```
group :test do
  gem 'simplecov', require: false
end
```

次に、`spec/rails_helper.rb`に以下を追加します。

```
require 'simplecov'
SimpleCov.start 'rails'
```
### テスト実行 
テストを実行します。
`bundle exec rspec`

RSpecテストを実行すると`coverage`フォルダが生成されます。生成されたファイルを開いて、カバレッジを確認します。


  
# 最後に
カバレッジを確認することで、テストが不足している箇所を効率的に特定することができると思います。最後まで読んでいただきありがとうございました。
GoogleスプレッドシートでExcelを編集する方法

# はじめに
Excelを持ってないけどExcelを編集する必要があったので、Googleスプレッドシートシートで代用しました。備忘のため簡単に手順を残しておきます。

## １．Excelをスプレッドシートにインポートする

Googleスプレッドシートを開き、空白のスプレッドシートを選択する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1955406/b3de845e-c90c-cf52-3af6-f33628a6c986.png)
　
無題のスプレッドシートの画面で、「ファイル＞インポート」を選択する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1955406/7b6adf3d-aea9-4c00-8fe7-910cacc9c53b.png)
　
ファイルのインポート画面で「アップロード」タブを選択し、編集したいExcelファイルをドラッグ・アンド・ドロップする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1955406/448ecc92-bf34-421e-1507-a6b0ee083443.png)
　

ファイルをインポートの画面でインポート場所を「スプレッドシートを新規に作成する」に変更し「データをインポート」を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1955406/bcc34924-b190-edd9-337c-75b0727f8265.png)

　
「完了しました」と表示されたら「今すぐ開く」を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1955406/62f60a00-d277-a114-23f5-ca1a2b4afa8e.png)
　
スプレッドシートでExcelが開けたので、必要な編集をする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1955406/1cea1822-3127-2a23-d06c-7345754122b3.png)


## ２．スプレッドシートをExcel形式でエクスポートする
ファイル＞ダウンロードのメニューから「MicrosoftExcel」を選択する。これでExcel形式でファイルがダウンロードできる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1955406/413d4d79-a219-3073-6d79-6b4b8ec8492c.png)

## ３．編集が終わったファイルを削除する
編集に使ったファイルを削除した場合は次の手順で削除する

GoogleスプレッドシートのTop画面から対象のファイルを選択し、削除を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1955406/f29b3f8a-51c2-d162-ee1d-fd9f0732403f.png)


「ゴミ箱に移動」を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1955406/eb7558dd-4686-dab7-63d2-9348e8e053db.png)

　

GoogleDriveのゴミ箱に削除したスプレッドシートがあるのでファイルを選択し、ゴミ箱ボタンを選択。これで完全に削除される。

:::note warn
※ゴミ箱があるのはGoogleスプレッドシートの画面ではなくGoogleDriveなので注意
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1955406/ff9da8ca-c1b9-e8bd-7307-d6c12de63e8c.png)


# 最後に
Excelはとても便利なものですが、ライセンスが高額。行政資料でもExcelのものが多いですが、できればExcel以外の選択肢を提示していただけるとハッピーライフです。
今、Chromeの正式版でChromeのローカル版AIが使用できるようになりました

オンライン体験アドレス：[https://chrome-ai.edgeone.app](https://chrome-ai.edgeone.app/)

Chrome内蔵AIは最初に申請フォームを記入する必要があり、Chromeの開発者版でのみ体験できました。現在、ユーザーは簡単な手順で正式版でこの機能を有効にできます。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3813484/d42579b5-217c-f98e-f965-85fe749b09ce.png)


「ウェブページの指示に従って設定を完了すると、デバッグページにアクセスできるようになります。ここでは、コードを迅速に修正して、ローカル AI の強力な機能を体験できます。

注意：Chrome API はまだドラフト段階であり、かなりの変更がある可能性があります。本ウェブページは Chrome 129 バージョンを基に開発されており、Chrome 128 バージョンの API とは互換性がありません。」

### なぜ Chrome にローカル AI があるのか？

- 過去の AI アプリケーションの使用において、私たちは通常、サーバー側のソリューションに依存することが習慣化しており、これが一部のユーザーにプライバシーへの懸念を引き起こしています。
- 一部の開発者は AI モデルをブラウザに移行しようと試みていますが、モデルのサイズは通常、ウェブページの中央値の約千倍です。これらのモデルはウェブサイトの前に共有されないため、異なるウェブページにアクセスするたびにこれらのモデルを再ダウンロードする必要があり、ユーザーのリソースを非常に消耗するソリューションです。

そこで Chrome はブラウザに Gemoni Nano を統合し、標準的な Web プラットフォーム API を公開しました。これは、ほとんどのデスクトップおよびノートパソコンで実行することを目的としています。Chrome 内蔵の AI の能力を活用することで、あなたのウェブサイトは独自の AI モデルをデプロイしたり管理したりすることなく、迅速に AI ドリブンなタスクを実行できます。

現在、プライバシーが確保されたモードでローカルの大規模なモデルを直接ウェブサイトで呼び出し、質問応答、翻訳などの機能を利用できます。

### **Chrome 内蔵 AI の Web 開発者にとっての利点は？**

- デプロイの簡便さ：ブラウザが自動的にモデルを配布するため、デバイスの能力を考慮しモデルの更新を管理します。これにより、ネットワークを通じて大型モデルをダウンロードまたは更新する責任を負う必要がなく、ストレージ解放、ランタイムメモリ制限、サービスコストなどの他の問題についても心配する必要がありません。
- ハードウェアアクセラレーションへのアクセス：ブラウザの AI ランタイムは最適化されており、利用可能なハードウェアリソース（GPU、NPU、または CPU にフォールバック）を最大限に活用できます。したがって、あなたのアプリケーションはあらゆるデバイスで最適なパフォーマンスを実現できます。

### デバイス上での AI 実行の利点は？

- 敏感なデータのローカル処理：デバイス上の人工知能は、プライバシー保護を高めることができます。たとえば、敏感なデータを処理している場合、ユーザーにエンドツーエンドの暗号化を利用した AI 機能を提供できます。
- 敏捷なユーザー体験：場合によっては、サーバー間の往復を省くことにより、ほぼ即時の結果を提供できます。デバイス上の人工知能は、利用可能な機能と最適でないユーザー体験との間の重要な差異を生み出すことができます。
- より広範な AI アクセス：ユーザーのデバイスは、一部の処理負担を軽減する代わりに、より多くの機能を利用することができます。たとえば、高度な AI 機能を提供する場合、デバイス上の AI を通じてこれらの機能をプレビューし、潜在的な顧客にあなたの製品の利点を理解してもらうことができ、コストを増やすことなく実現できます。このハイブリッドアプローチは、特に頻繁に使用されるユーザーフローにおいて推論コストを管理するのにも役立ちます。
- オフライン AI 利用：ユーザーは、インターネット接続がない場合でも AI 機能にアクセスできます。つまり、あなたのウェブサイトやネットワークアプリケーションは、オフラインまたは不安定なネットワーク接続の状況でも正常に機能できます。

### **ブラウザアーキテクチャと API**

主にタスク API を通じて内蔵の AI 機能にアクセスします。タスク API は、割り当てられた最適なモデルを対象に推論を実行することを目的としています。

Chrome では、これらの API は微調整または専門モデルを用いて Gemini Nano に対して推論を実行することを目的としています。Gemini Nano はほとんどの現代デバイスでローカルに実行されるように設計されており、特に要約、書き換え、分類などの言語関連のユースケースに最適です。

**重要な用語：** *微調整* は、新たなモデルをダウンロードすることなく、特定のタスクを実行するためのモデルの能力を動的に向上させる方法です。

二種類の API を提供します：

- **プロンプト API**：自然言語で表現された任意のタスクを内蔵の大規模言語モデル（Chrome の Gemini Nano）に送信します。
- **微調整（LoRA）API**：低ランク適応微調整を使用してモデルの重みを調整し、内蔵の LLM のタスクに対するパフォーマンスを向上させます。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3813484/98b08265-f284-389d-37ca-7452e6201848.png)


### ユーザーに提供できる能力は？

- 人工知能を活用したコンテンツ消費：要約、翻訳、内容に関する質問への回答、分類および特徴分析を含みます。
- 人工知能支援によるコンテンツ創作：執筆支援、校正、文法の訂正及び書き直しを含みます。

要約API：

- 会議に遅れて参加したり、完全に見逃したユーザーのための会議記録の概要。
- 顧客関係管理（CRM）における対話の要点。
- 複数の製品レビューの文または段落単位での要約。
- 長文記事の要点を示し、読者が記事の関連性を判断するのを助けます。
- フォーラム内での質問を要約し、専門家が専門分野に最も関連性の高い質問を見つけやすくします。

執筆と書き直しのAPI：

- 初期のアイデアとオプションの背景に基づいて執筆します。例えば、銀行に正式なメールを書いて信用枠の増加を求める背景が長期の顧客である場合。
- 既存のコンテンツを最適化するために、テキストの長さやトーンを調整します。たとえば、短いメールを書き直して、より丁寧で正式に聞こえるようにすることができます。
ステートレス・ステートフルメモ

ネットワークの世界で「ステートレス（stateless）」と「ステートフル（stateful）」という用語は、サーバーやアプリケーションがクライアントとの通信において状態（state）を維持するかどうかを指しています。

### ステートレス（Stateless）
- **定義**: ステートレスなシステムは、各リクエストを独立して処理し、過去のリクエストやセッション情報を保持しません。
- **特徴**:
  - 各リクエストが完全に自己完結している。
  - サーバーはクライアントの状態を保存せず、リクエストのたびにその都度全ての情報が提供される必要がある。
  - 例として、HTTPプロトコルが典型的なステートレスプロトコルです。各リクエストは他のリクエストとは独立して扱われます。
  - **利点**: スケーラビリティが高く、サーバーが負荷を受けにくい。
  - **欠点**: 連続したやり取りが必要な場面では効率が悪くなる可能性がある。

### ステートフル（Stateful）
- **定義**: ステートフルなシステムは、クライアントとサーバーの間で状態情報を維持し、リクエスト間の連続性を持たせます。
- **特徴**:
  - クライアントとサーバーはセッションやコネクションを維持し、過去のリクエストや応答の情報を覚えている。
  - 例として、データベース接続やFTPセッション、SSH通信はステートフルです。
  - **利点**: 継続的なやり取りが必要な場合に効率的で、セッション情報が保持されるためスムーズに操作が行える。
  - **欠点**: サーバーが状態を管理するため、スケーラビリティが低下し、サーバーのリソース負荷が高くなる可能性がある。

簡単に言うと、ステートレスはリクエストごとに独立した通信を行い、ステートフルは通信の連続性を持つという違いがあります。
HTMLについて調べてみた

# 背景・目的
　こんにちは．プログラミング初心者です．現在私は大学生で，インターンシップ型アルバイトに参加させていただいており，その中でAngulrを用いたアプリケーション開発をすることとなり，急遽HTML/CSS, JS, Angulrの勉強をすることになりました．
　社会に出たら今までやってきたこととは違うことなんていくらでも挑戦するよなということで，さっさと切り替えて勉強していきましょう．
 　とりあえず今回の目的は，HTMLの軽い実装と基本的（ド偏見）なことを図書館で借りてきなtextを中心に分からないことなどを適宜，web情報で学んでいくものとします．

## 使用環境
Windows11 
VScode
※VS環境は昔html/cssは触ったことがあり，構築済みだったのでここでは省略します
## 参考文献
> https://x.gd/7CFdo

## 学んだ内容
### HTML
- 基本文法
- タグ
- テーブル
- 入力ボックス

## HTML
### 基本文法
　基本的にはタグという，日本語の会話文でいうところの括弧（「」）の様なものを挟むことにより，コードは構築されている．さらにタグの中に，属性，値と呼ばれる要素があり，基本的には入れ子構造である．
 イメージとしては重箱です．タグについては後程記述しますが，<html>タグで構成された重箱，その中に一段目は<head>タグ，二段目に<body>タグなど大まかに構成され，各階層にはそれぞれまた複数のタグで構成されている．イメージとしてはおかず（タグ同士）が混ざりあわないように仕切りの役割を兼ねているという意解釈です．属性はいわば，おかずの特徴を示すタグで，形容詞的なイメージで，値はおかずの備考となる情報．食材の原産地を＝で結ぶ感じです．分かりにくいですが，以下みたいなイメージでいいと思います．
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3807183/1c34e8e3-892a-20c4-f0c3-6e9ffd4c1940.png)

### タグ
- 見出しタグ
```
<h1> ここに記述 </h1>
```
これは見出しタグで，numberには1~6まで入る
- メタ要素タグ
```
<meta>
```
これはメタ要素を記述するタグで，終了タグは無い.
このタグの目的は，ブラウザなどに伝える情報を記述する際に用いる．具体的な例を出すと，文字コードや検索画面で表示される文章や検索の際に対象となる為の単語などを既述する
- 段落タグ
```
<p></p>
```
段落をひとまとまりにして表示するコード
- 画像タグ
```
<img src="カレントディレクトからの相対パス",alt="画像表示できない場合の例外時の出力">
```
上のコードは画像を出力するためのコードで，srcの値に画像のパスを記述する．なおaltの例外処理を忘れないように注意．画像の処理がダメなのか，webのビルド自体が上手くいかなかったのかわからなくなった．
なお，終了タグは無いので注意
- listタグ
```
<lo>
  <li>番号付きlist</li>
</lo>
<ul>
  <li>箇条書きlist</li>
</ul>
```
### テーブル
テーブルのイメージは下記のとおりです．灰色の部分は非表示で，\<tr>は行を表します．第一行には<th>が来て各列の見出しとなるセルをあらわす．\<td>は表データを表す．
```
<table border="1">
  <tr>
    <th>列名１</th><th>列名２</th><th>列名3</th>
  </tr>
  <tr>
    <td>1<td>2</td><td>3</td>
  </tr>
  <tr>
    <td>4</td><td>5</td><td>6</td>
  </tr>
</table>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3807183/92a7439f-24be-c84f-9dd8-28b5943963d9.png)

### 入力ボックス
これはメタ要素タグと同じで終了タグがないタイプ
```
<input type="text">
```
これで土台は完成．ここからtypeの値を変えていったり，属性を足すことで変更できるみたい．
## 結論
 改めて，今までやってきた言語と毛色が違う．初心者はこの言語から始めるのはやめとけって言われるのにも納得が出来る．
 とりあえずタグの概念と，属性，値の考え方さえ掴んどけば，何とかなりそうな言語だと感じた．
【初心者】Node.js（Express）でHTMLを読み込もうとしたらCSSを拒否された件について

こんにちは。
最近になってNode.jsの勉強を始めたのですが、開幕早々躓いた点がありましたので備忘録として残しておきます。
ちなみに私はNode.jsのことを少し前までJavaScriptのライブラリの一種みたいに考えていた人間です……。
（だって……「～.js」みたいな表記してるから！）
もし何か間違っている箇所などありましたらご教授頂けますとありがたいです。

▼今回導入や実行に辺り参考にさせて頂いた記事です。ありがとうございます。

https://qiita.com/ryome/items/16659012ed8aa0aa1fac

***

さて、Node.js、Expressを導入してローカルサーバーを立ち上げる所までは順調に進んでおりました。
（Hello World!を表示させる定番のアレですね）
そして自分が制作していたWebページを表示させてみようと思い、
先程の記事を参考にHTMLを読み込ませる記述を書いてみました。
```Node.js
// 静的ファイルの提供とキャッシュの有効化
app.use(express.static('/', { maxAge: 86400000 }));

// HTMLリクエスト
app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, './index.html'));
});

// 中略

// 今回ポート番号は5000に設定してみました
app.listen(5000, ()=> {
	console.log('Server listening on port 5000');
});
```
いざローカルサーバーに接続！　……してみると、確かにindex.htmlが読み込まれました！

ですが、CSSファイルが読み込まれておらず骨組みだけの状態になってしまっておりました。
そこでChromeの開発者ツールにて確認してみると、consoleタブに以下のエラーが吐かれておりました。

```
Refused to apply style from 'http://localhost:5000/css/style.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
```

え、全然見たことのないエラーだ……と不安になり一旦Google先生へ翻訳を依頼。
直訳が以下です。

:::note warn
MIME タイプ (「text/html」) がサポートされているスタイルシート MIME タイプではなく、厳密な MIME チェックが有効になっているため、「http\://localhost:5000/css/style.css」からのスタイルの適用を拒否しました。
:::

MIMEタイプって何だ。ということで調べてみます。

▼今回参考にさせて頂いたサイト様です。

https://wa3.i-3-i.info/word15786.html

調べてみるとサーバーとブラウザ間のやり取りで扱われる「**各ファイルの種類を判別するためのデータ**」だそう。
こちらのエラーの解決方法として色々探したところ、以下の方法が紹介されておりました。

:::note info
CSSを読み込むlinkタグ内のtype属性をきちんと指定する（今回の場合は「text/css」）
:::

なるほど、いつも何気なく書いたり書かなかったりしていたtype属性にはそんな重要な役割があったのか！　と思いheadタグ内を修正したのが下記です。

```HTML:HTML
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>●●●</title>
	<link rel="stylesheet" type="text/css" href="./css/style.css">
</head>
```
 
しかし上記を試すも解決には至らず……悪戦苦闘した結果、ちゃんとCSSを読み込めた方法が以下になります。

```Node.js
// 静的ファイルの提供とキャッシュの有効化
app.use(express.static('public', { maxAge: 86400000 }));

// HTMLリクエスト
app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, 'public/index.html'));
});
```

Node.js用のJS（index.js）とポートフォリオ用のindex.htmlを別階層に分けました！
どうやらHTMLリクエストの上で書いている「**express.static**」が鍵になっていたそうです……そっちか！
こちらは**ミドルウェア関数**と呼ばれる関数だそうで、下記のサイトでは以下の注意点が記載されておりました。

https://expressjs.com/ja/starter/static-files.html

:::note warn
express.static関数に指定するパスは、nodeプロセスを起動するディレクトリーに対して相対的です。
:::

▼ちなみにミドルウェア関数についての説明がされているのはこちらです。

https://expressjs.com/ja/guide/writing-middleware.html#:~:text=%E3%83%9F%E3%83%89%E3%83%AB%E3%82%A6%E3%82%A7%E3%82%A2%20%E9%96%A2%E6%95%B0%E3%81%AF%E3%80%81%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88,%E6%A8%A9%E9%99%90%E3%82%92%E6%8C%81%E3%81%A4%E9%96%A2%E6%95%B0%E3%81%A7%E3%81%99%E3%80%82

つまり、きちんとディレクトリー（フォルダ）を作って指定する必要があった、ということでしょうか。
（色々疑問点が浮かび上がったのですが、この辺りはまだまだ理解が追いついていないので勉強頑張ります……！）

## まとめ
HTMLのtype属性がサーバーとブラウザ間で重要な役割を担っていたのは全然知りませんでしたので、
今回逆にエラーが吐かれて良かったのかなと思いました（怪我の功名……？）
今後はなるべく意識して指定していこうかなと思います。
そして、お試しとはいえ一気にごちゃごちゃと同じ階層内にファイルを置かない・作らないも気をつけねばならないと感じました……。
もし学習を始めたばかりの人で同じような状況に置かれてしまった人がおりましたら、手助けになれば幸いです。