OmniAICreator/Qiita-1.07M huggingface dataset:
Next.js + Vercel でローカルでは build できるのにVercel上でエラーになるときに試すこと備忘録

## 概要

Next.js + Vercel でローカルでは build できるのにVercel上でエラーになるときに試すことについて、
備忘録的にまとめておきます。


## やること

### node_modules を一度削除

`node_modules` を一度削除して、
`npm install` をやり直してみましょう。

```bash
$ rm -rf node_modules
$ npm install
$ npm run build
```


この時、 build で、なんらかの理由で

```
info Creating an optimized production build .Bus error: 10
```

のような Bus エラーが起きた時は、
もう一度

```bash
$ rm -rf node_modules
$ npm install
$ npm run build
```
を実行します。


### 個別に npm install をやり直す

ローカルで `npm run build` が通っているのにもかかわらず、
Vercel上で

```
Error: Cannot find module '@headlessui/tailwindcss'
```

などと言われる時があります。
その時は今一度

```
npm install @headlessui/tailwindcss
```

をしてから、git 上で

```
	modified:   package-lock.json
	modified:   package.json
```

となっているのを確認して、`git push`し、再度Vercel上でビルドをしてみましょう。
Reactを基本からまとめてみた【基礎 / Reacthook / Todoアプリを作成】

## コンポーネント・ファイル構成
```
 src
  ├── components
       └── Todo.jsx
  ├── pages
       └── TodoList.jsx
  ├── App.jsx
```



## 参考サイト
[【React基礎編】#01 たった1hで完全理解！ 現役エンジニアと Reactを用いたTODOアプリ作成](https://www.youtube.com/watch?v=YCnUl0eXFvs)
[【React基礎編 】#02 現役エンジニアと学ぶReactの主要な関数(hooks)を完全マスターしてフロントエンドエンジニアへ](https://www.youtube.com/watch?v=5-7Fm5QxSrI&t=205s)
【サーバ構築】 Linuxサーバ と Windowsサーバ について学ぼう

##### Windows Server サーバ構築
>①VMwareのインストール【仮想化ソフト】
②Windows Server のインストール【サーバ】
③Windows Server2019にActive Directory機能を追加
④DHCPサーバの導入
　1 DHCPのインストール完了
　2 DHCPサーバの構成
　3 DHCPスコープの設定

#### Linux サーバ構築
###### FTPサーバ
>⓪VirtualBoxで仮想マシンを作成し、CentOSをインストール済み
①vsftpdのインストール【FTPサーバ】
②作成したFTPサーバの設定変更
③FFFTPのインストール【FTPクライアントソフトウェア】
④FTPクライアントソフトウェアでFTPサーバへの接続

###### WEBサーバ
>①Apacheのインストール【Webサーバ】
②SSHサーバ


## 環境構築
##### Windows Server 2019(ISOをダウンロード>個人情報を入力し、ダウンロード)
https://www.microsoft.com/ja-jp/evalcenter/evaluate-windows-server-2019

##### VMware Workstation 17 Player for Windows の試用
https://www.vmware.com/jp/products/workstation-player/workstation-player-evaluation.html

#### 「FFFTP」定番FTPクライアントソフト
https://forest.watch.impress.co.jp/library/software/ffftp/

#### Download VirtualBox
https://www.virtualbox.org/wiki/Downloads

#### CentOS
公式ページからどうぞ

#### WinSCP
https://forest.watch.impress.co.jp/library/software/winscp/

## 参考文献
##### たった2日でわかるLinux Cent OS7.0対応 （単行本）
https://www.shuwasystem.co.jp/book/9784798042565.html


##### 評価版 Windows Server 2019をインストールする方法（VMware Workstation Player）
https://osagoublog.com/virtual-machine/vmware/windowsserver2019-install

#### Windows Server 2019講座｜第1回【初期設定】リモートデスクトップ・固定IPアドレス・コンピューター名の変更
https://www.youtube.com/watch?v=ZaiVTKWvcuc

#### Windows Server 2019講座｜第2回 Active Directory機能を追加
https://www.youtube.com/watch?v=hSTascnywV0

#### Windows Server 2019講座｜第3回 DHCPの導入とスコープの作成
https://www.youtube.com/watch?v=VlmznPvqJc4

## エラーが出た場合
#### 【解決】VMware エラー「Time out. EFI Network. . .」
https://www.momohuku.tokyo/post-160515/

## 便利なツール
#### 【ID Manager】シンプルなパスワード管理
http://www.vector.co.jp/soft/dl/win95/util/se178553.html
DreamGaussianで3Dモデル生成してみました。

昨日DreamGaussianという3Dモデルを生成するモデルを試してみました。
こちらは先週、中国の北京大学が公開した、画像やテキストから3Dモデルを生成するモデルです。特徴は処理時間が速いです。
初めての３Dモデル作りなので、チューニング方法はよくわからなくて、論文＋コードを参照してやりました。

まずはデフォルト設定で車のモデルを作ってみました、使用した画像は以下の写真です。![mer2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/a8604055-7981-2da1-4b77-892f880035ae.jpeg)

できた3Dモデルは、以下の通りです。
![动画.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/14ae1bb0-1409-a9a7-56f2-a10253e6ded8.gif)



なんとなく車のようなモデルはできますね。処理時間は2-3分程度でした。（GPUはA100）
初めての試しなので、速いかどうかあまりわからないですが、DreamGaussianの開発者によると、他のモデルでは少なくても１０分はかかるそうです。


もう少しチューニングしたいと思って、イテレーション回数とサイズを大きくしました。デフォルトの状態だと500回みたいなので1000回に上げました。処理時間も５分ほどに延びました。
できたモデルは、以下の通りです。

![动画2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/d77bc896-5762-d259-12cc-931c48d39ec5.gif)
いかがでしょうか。あまり変わってないような感じですね。（写真の質がよくないか、もしくは私のチューニングが下手かもしれません）


ちなみに、フシギダネのモデルも作ってみました。車よりうまくできました。
![333.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/dc7e477f-5fd6-1336-2b74-bac2436fca47.png)

github:https://github.com/dreamgaussian/dreamgaussian
ホームページ:https://dreamgaussian.github.io/


![动画3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/6b200663-e579-ba13-ebd2-a245b9d478e0.gif)
![动画4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/bb48df0b-1635-75dd-1e3f-ee8391836304.gif)
【初学者向け】今さら聞けない！セッション（Session）ってどんなもの？

# はじめに
こんにちは。Sessionという言葉を耳にしたことはあるけど詳しくは知らない方もいらっしゃると思います。そこで今回はセッションについて初学者でもわかるように説明したいと思いました。

# 概要
[前回](https://qiita.com/nakaizumi_slj/private/607cf6c8cbe005ca2233)に引き続き、ウェブ開発とプログラミングの世界で重要な役割を果たす要素について説明します。今回のトピックは「セッション（Session）」です。セッションはウェブアプリケーションの中で、ユーザー体験やデータ管理において欠かせない機能です。この記事では、セッションが何か、なぜ重要なのか、そしてどのように機能するのかを詳しく解説します。

# セッションの主要な仕組み
セッションの仕組みは次のように構成されています。

#### 1. セッションの開始
ユーザーがウェブアプリケーションにアクセスすると、新しいセッションが開始されます。
このとき、サーバーはセッションIDを生成し、通常はクライアントにCookieとして送信します。
セッションIDはユーザーのセッションを一意に識別するための鍵です。

#### 2. セッションデータの保存
セッションデータは、ユーザーごとに異なる情報を保存するために使用されます。この情報は通常、サーバー側にデータベース、ファイル、またはメモリなどの永続的なストレージに格納されます。
セッションデータには、ユーザーの認証情報、設定、一時的なフォームデータなどが含まれます。

#### 3. セッションデータの更新
ユーザーがウェブアプリケーション内で操作を行うたびに、セッションデータが更新されます。たとえば、ユーザーが設定を変更すると、その情報がセッションデータに反映されます。

#### 4. セッションの終了
ユーザーがログアウトしたり、セッションが一定時間経過してタイムアウトした場合、セッションは終了され、セッションデータはクリアされます。

# セッションの重要性
セッションはウェブアプリケーションにおいて非常に重要です。以下はその重要性の一部です。

#### 1. セッション管理
セッションはユーザーの[セッションを管理](https://wa3.i-3-i.info/word1792.html)し、連続した操作を可能にします。
例えば、ショッピングカートの内容を維持するなど、ユーザーエクスペリエンスを向上させます。

#### 2. ユーザーエクスペリエンスのカスタマイズ
セッションを使用して、ユーザーに合わせたカスタマイズされたコンテンツや設定を提供できます。
これはユーザーエクスペリエンスを向上させるための強力なツールです。

#### 3. ログイン情報の保持
セッションはログイン情報を保持し、ユーザーが再度ログインせずにアクセスできるようにします。

#### 4. ウェブサイトのパフォーマンス向上
セッションはウェブサイトのパフォーマンス向上に寄与し、ユーザーに高速な読み込み速度を提供します。

# 終わりに
セッションについて少しでも理解が深まったら幸いです。
記事の内容など、何かございましたらコメントお願いいたします。
読んでいただきありがとうございました。
Laravelでweb.phpにrouteを書いてもApacheの404エラーになるのは.htaccessの問題

通常、web.phpにURIを書けば動くはずだが
404エラーになる。
それもLaravelの吐き出すグラフィカルな404ではなく
旧来のApacheが出力する文字だけの404
↑ここに気がつくのが遅くてずっとweb.phpやcacheを疑っていたが
Laravel10の.htaccessは

```
<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>

    RewriteEngine On

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Send Requests To Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>
```

なんですが、
この
``RewriteCond %{REQUEST_FILENAME} !-d``
が曲者で
publicにディレクトリがなければって条件で
って意味なんですよね。

で、ワイは何をしていたかというと
publicに/event/enquete/imgというディレクトリを作り画像を置き
web.phpで
/event/enquete/login.htmlはLaravelを実行させたいと
```
Route::get('/event/enquete/login.html', ['uses' => 'App\Http\Controllers\EnquetemainviewController@index','as' => 'enquetemainview.index']);
```
していたら、
``RewriteCond %{REQUEST_FILENAME} !-d``
でpublicに/event/enquete/ディレクトリあるからhtaccessのindex.php行にはたどり着けずなので、Apacheに処理が返り、
でも、publicの/event/enquete/にはindex.htmlは無いから
Apacheが404エラーを出していた。。って寸法。


ということで、以下のように
publicに実ファイルが存在しなかったときのみ、Laravelのindex.phpが動くようにコメントアウトした。
```
<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>

    RewriteEngine On

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect Trailing Slashes If Not A Folder...
    #RewriteCond %{REQUEST_FILENAME} !-d  **コメントアウト
    #RewriteCond %{REQUEST_URI} (.+)/$  **コメントアウト
    #RewriteRule ^ %1 [L,R=301]  **コメントアウト

    # Send Requests To Front Controller...
    #RewriteCond %{REQUEST_FILENAME} !-d  **コメントアウト
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>
```


気づくのに時間がかかった・・悔しい
python-flaskとdart-flutterのandroidえみゅでのWebsocket通信で躓いた話

## はじめに
こないだの大阪技育2023のときにタイトル通りに躓いてた。
大阪技育ではてくてくてっくという二人チームで、タスクメイドというリーダーとメンバーでメイドを板挟みにしてタスクを管理してもらうアプリを出しました。
相方の圧倒的プレゼンと始めたばかりとは思えないflutterとメイドパワーで最優秀賞いただきました。ありがとうございます。

## 結論
androidからみてlocalhostはandroid自身なので、仮想ルータがホストOSに割り振っているIPを指定するといいと教えてもらった。


公式: 
Android Emulator のネットワークをセットアップする
[https://developer.android.com/studio/run/emulator-networking?hl=ja]

具体的な実装方法が載ってるサイト: 
Androidのエミュレーターから自身のPC(localhost)へ接続
[https://araramistudio.jimdo.com/2018/01/11/android%E3%81%AE%E3%82%A8%E3%83%9F%E3%83%A5%E3%83%AC%E3%83%BC%E3%82%BF%E3%83%BC%E3%81%8B%E3%82%89%E8%87%AA%E8%BA%AB%E3%81%AEpc-localhost-%E3%81%B8%E6%8E%A5%E7%B6%9A/]

Flutterを使いAndroidのエミュレーターでローカルホストに接続
[https://note.com/_hi/n/n0dfe96c434e8]

【Android】エミュレータでホストOSのWebサーバに接続する
[https://atsum.in/android/access-host/]

### 環境
VScodium
拡張: dart, flutter 
えみゅ: Pixel 6a API 33
Python3コマンドが使えない！

# 環境
windows11
# 状況
環境Pathを通して,Pythonが使えるようになったのに，`Python3 -u`で実行しようとしたら使えなかった．
しかし，`Python -u`なら動いた．
# 解決策
まさかの方法でした．`C:\Users\ユーザー名\AppData\Local\Programs\Python\Python310`の中にある`Python.exe`ファイルをコピペして`Python3.exe`に名前を変更することで解決しました．
# 後記
調べてもあまり情報が出てこなくて困りました．ある記事では，「Pythonコマンドを使えばよいではないですか」と書かれていました．確かに，その通りなのですが，Python3コマンドを使いたいかったのです...
どなたかの役に立てばうれしいです．
Railsを使ったファイルアップロード処理方法

### Rails Active Storageの使い方ガイド

Ruby on Railsには、ファイルアップロードを簡単に扱うためのモジュールとして`Active Storage`が提供されています。この記事では、`Active Storage`を使ってファイルアップロード機能をRailsアプリケーションに組み込む方法を解説します。

#### 1. 必要なGemのインストール

まず、`Gemfile`に`active_storage`を追加します。Rails 5.2以降であれば、デフォルトで`active_storage`はGemfileに含まれていますが、それ以前のバージョンや特定の理由で含まれていない場合は以下のように追加します。

```ruby
gem 'activestorage', '~> 5.2'
```

追加したら、以下のコマンドを実行してgemをインストールします。

```bash
bundle install
```

#### 2. Active Storageのインストール

次に、以下のコマンドを実行してActive Storageの必要なファイルやマイグレーションを生成します。

```bash
rails active_storage:install
```

このコマンドにより、Active Storageのためのマイグレーションファイルが生成されます。

#### 3. マイグレーションの実行

マイグレーションファイルが生成されたら、以下のコマンドでデータベースに必要なテーブルを作成します。

```bash
rails db:migrate
```

以上の手順により、既存のRailsプロジェクトにActive Storageを新たに導入することができます。次にモデルの設定やストレージの設定など、Active Storageの利用に必要な設定を進めてください。

#### 4. ストレージの設定

`Active Storage`はローカルストレージやクラウドストレージサービス（Amazon S3、Google Cloud Storage、Microsoft Azure Storageなど）をサポートしています。この設定は`config/storage.yml`で行います。

例えば、開発環境でローカルストレージを使用し、本番環境でAmazon S3を使用する場合、以下のように設定します。

```yaml
# config/storage.yml

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

amazon:
  service: S3
  access_key_id: your_access_key_id
  secret_access_key: your_secret_access_key
  region: your_region
  bucket: your_bucket_name
```

`config/environments/development.rb`:

```ruby
config.active_storage.service = :local
```

`config/environments/production.rb`:

```ruby
config.active_storage.service = :amazon
```

#### 5. モデルに添付ファイルを追加

例として、ユーザーのプロフィール画像をアップロードする機能を考えます。`User`モデルに以下のように追記します。

```ruby
class User < ApplicationRecord
  has_one_attached :profile_image
end
```

`has_one_attached`メソッドを使って、`User`モデルに`profile_image`という名前のファイルを添付します。

#### 5. フォームでファイルアップロードフィールドを使用する

ユーザーのプロフィール画像をアップロードするためのフォームを作成します。

```erb
<%= form_with(model: @user) do |form| %>
  <div class="field">
    <%= form.label :profile_image %>
    <%= form.file_field :profile_image %>
  </div>

  <%= form.submit %>
<% end %>
```

#### 6. 画像の表示

画像を表示する場合は以下のように`rails_blob_path`や`rails_representation_path`ヘルパーを使用します。

```erb
<%= image_tag @user.profile_image if @user.profile_image.attached? %>
```

以上の手順に従うことで、`Active Storage`を使ってRailsアプリケーションにファイルアップロード機能を追加することができます。
PHPStormが起動しない (Cannot connect to already~)

# PHPStormが起動しない (Cannot connect to already~)

## エラーメッセージ

```
Cannot connect to already running IDE instance. Exception: Process 482 is still running
```

## 解消法

該当のプロセスをkillする

自分の場合はカレンダーアプリを終了したら正常に起動しました
```
user    482   xxxx /System/Applications/Calendar.app/Contents/MacOS/Calendar
```

## リファレンス

コミュニティにも報告が上がってる
https://intellij-support.jetbrains.com/hc/en-us/community/posts/13541697317906-Error-while-opening-intellij-Cannot-connect-to-already-running-IDE-instance-Exception-Process-2-837-is-still-running-
AWSで Active Directoryの構築(オンプレミス⇔AWS）


# AWSで Active Directory を利用

AWSでActive Directoryを利用する際に構築可能な３つのパターンが存在している。

| |Active Directory Server<br>on EC2  | AWS Directory Service<br> Simple AD | AWS Directory Service <br>Managed Microsoft AD |
|:------|:------|:------|:------|
|ケース | オンプレミスWindows Server での運用とあまり変えたくない方  | 小規模なディレクトリやAWS 内で完結する方  | 高い可用性と耐久性が必要なActive Directory を新たに構築したい方  |
|運用・保守 | 自身で設計| AWS側で管理 <br> Samba4 ベース | AWS側で管理 <br>Windows Server 2019 ベース  |
|セキュリティ| 自身で設計| CloudTrailを利用して監査ログの取得<br> 自動アップデート |CloudTrailを利用して監査ログの取得<br> 自動アップデート  |
|バックアップ   |自身で設計|AWS側で設計<br>スナップショットを利用 | AWS側で設計<br>スナップショットを利用 |
|ユースケース  | ・Active Directory 最新版の機能を使う<br>・ハイブリッド構成かつシングルドメイン  |・小規模なユーザ管理、高度なグループポリシーを使用しない<br> ・AWS 内で完結  |・高い可用性と耐久性が必要<br>・オンプレとは信頼関係を維持  |

# ① Active Directory サーバー on EC2
オンプレミスWindows ServerをAmazon EC2で立てる為、ほとんど変えることなく使うことが出来る。
### メリット
    ・Windows Server の標準機能が利用可能
    ・操作手順はオンプレミスとほとんど同じ
### デメリット
    ・OS 以上のレイヤは運用保守の検討が必要 (Windows Update など)
    ・冗長化も可能。（EC2 を複数台立てた上で冗長化設計が必要）
    ・高額な料金になる場合がある
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/34290d0a-1d95-040e-21c9-e2775c6223d0.png)

# ② AWS Directory Service (Simple AD)
小規模なディレクトリやAWS 内で完結する場合

https://docs.aws.amazon.com/ja_jp/directoryservice/latest/admin-guide/directory_simple_ad.html

```
Simple AD
    Samba 4 Active Directory Compatible Server を使用するスタンドアロンのマネージドディレクトリです
        ・スモール – 最大 500 ユーザー (ユーザー、グループ、コンピュータを含めて約 2,000 オブジェクト) をサポートします。
        ・ラージ – 最大 5,000 ユーザー (ユーザー、グループ、コンピュータを含めて約 20,000 オブジェクト) をサポートします。
```
### メリット
    ・手軽に可用性や対障害性を向上させることができる
    ・従量課金で利用可能
### デメリット
    ・AWS 外のコンポーネントの管理ができない
    ・既存ドメインとの信頼関係の設定不可
    ・ユーザ管理用に別途 EC2 インスタンスが必要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/735ea7d2-bfc9-9dcd-9acf-597da6302eb3.png)

# ③AWS Directory Service (Managed Microsoft AD)
高い可用性と耐久性が必要なActive Directory を新たに構築する際に

https://aws.amazon.com/jp/directoryservice/?nc=sn&loc=1

https://docs.aws.amazon.com/ja_jp/directoryservice/latest/admin-guide/ms_ad_migrate_users.html

```
Managed Microsoft AD
    ・Windows Server 2019 を使用
    ・Standard：最大 30,000* のディレクトリオブジェクト (ユーザー、グループ、コンピュータなど) をサポート、Enterprise：最大 500,000* のディレクトリオブジェクトを有する企業組織をサポート
```

### メリット
    ・手軽に可用性や対障害性を向上させることができ、大規模な運用が可能
    ・既存の Microsoft AD 認証情報を使用して AWS リソースにアクセスすることで、よりスムーズなユーザーエクスペリエンスを提供できます
### デメリット
    ・シングルフォレスト・シングルドメイン構成が必須
    ・WindowsのAdministrator 権限は利用不可。別途AdminがAWSから付与される
    ・Simple ADと比較すると料金やや高

### ③-1　AWSのドメインと、オンプレミスのドメインを２つ作り、信頼関係の構築の場合
    ・２つのドメインを作成することで、信頼関係を構築するというような形を取ることが出来る。
    ・- 拠点のコンピューターの管理はオンプレミスのActive Directoryで行う
    ・- AWSに移行したサーバーの管理はAWSのクラウドの方での管理を行う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/93dccf65-a815-43cb-00fa-58f93d060a42.png)


### ③-2　ドメインを変えなく場合、EC2で構築する方法
    Active DirectoryにManaged Microsoft ADを使わずにActive Directoryサーバーon EC2を使用する。この際、冗長化のため2台作成する。３台（オンプレミス１台、AWS2台）で１つのドメインとして構築。どちらかの拠点が使えなくなってしまった場合でも相互にリレーションとなり保管が可能となる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/54d7aa7f-abd1-ce7f-5319-6bb02ff410c7.png)
DMZ 【DeMilitarized Zone】インターネット 非武装地帯 / 非武装セグメント

# DMZ 【DeMilitarized Zone】 非武装地帯 / 非武装セグメント
DMZとは、インターネットなどに接続されたネットワークで、ファイアウォールなどの機器を用いて外部と内部の両ネットワークの中間に設けられたネットワーク領域のこと。もとは軍事用語で、紛争地域の軍事境界線付近に設定された軍事活動の禁じられた地域のことを指す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/187231eb-76da-bb6e-88a5-215a5aee83f3.png)


# DMZ領域（DMZネットワーク）の種類
 ### シングルファイアーウォール型
一つのファイアウォールだけを設置する方法。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/50524ac9-b0fe-9dea-a9b0-7591a1a4fd52.png)

 ### デュアルファイアーウォール型
ネットワークの内側と外側の間に2つのファイアウォールを設置し、そのの間にDMZを配置します。
DMZヘは1つのファイアウォールを通過すればアクセスできる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592268/93a3c130-b704-6b5e-5a9b-be4d388c9ac0.png)

# DMZのメリットとデメリット
|  |  |
|:---------|:---------|
|メリット|標的型攻撃を防ぐことができる<br> 情報漏洩を防ぐことができる |
|デメリット|ネットワークの構成や設定が複雑になる<br> 社内ネットワークは守れるが、公開サーバーを守るものではない |

# DMZの出来ることと出来ないこと
|  |  |
|:---------|:---------|
|出来ること|インターネットからの内部情報の保護<br> サイバー攻撃などへの対策 |
|出来ないこと|ウィルス感染の防止<br> Webアクセスの通信内容による防御|
【WebAPI】エラー情報について意図的に不正確な情報を返したいケース

### 意図的に不正確な情報を返すケースとは？
:::note
エラーはなるべく具体的に正確に返すべきであるが、セキュリティやそのほかの理由からあえてやや情報を曖昧にしたいケースも存在する。
:::

##### 例1：ブロック機能
SNSやチャット系のサービスでは、嫌がらせを受けたり、やり取りを継続したくない時に相手をブロックする機能がある。この時、ブロックされた人がブロックした人のユーザー情報を取得しようとした場合どのするべきか？
正確にエラーを返す場合、これは認可のエラーになるため`403`を返し、エラー情報として相手がブロックしていることを伝えることになる。しかしブロックしたことを知られてしまうと、さらにトラブルに広がってしまう可能性もあります。

このような場合は、**「ブロックされた側から見るとブロックした側はもはや存在しないと同義」とみなして`404`を返す**といったことも可能。

* 正確に返す場合
    * 403の認可エラー
* あえて不正確に返す場合
    * 404のnot found
* なぜか？
    * ブロックしたことを知られてしまうと、さらにトラブルに広がってしまう可能性もあるため

##### 例2：ログインの失敗時
ログインの際にメールアドレスとパスワードを送信した際に、メールアドレス自体が存在しないのか、メールアドレスは存在するけれどパスワードが違うのか、それともユーザーが凍結されて使えないのか、といった情報を返すことが想定される。

そうした情報はログインに失敗したユーザーに親切な情報を与える一方で、不正ログインをはじめ悪意を持ったユーザーに親切な情報を与えてしまうことにもなりかねない。

したがってあまり多くの情報を与えずに、ログインがうまくいかない人はパスワードリセットなどの別の手段でログインを試してみてね、という誘導に留める方が安全なケースも多い。

* 正確に返す場合
    * ログイン失敗理由を正確に返す
* あえて不正確に返す場合
    * 正確な原因は返さず、別の手段でログインするように誘導する
* なぜか？
    * 悪意のあるユーザーに親切な情報を伝えてしまう可能性があるため


:::note
実際の現場ではAPIの性質に強く依存するため、上記のようなケースは場合による。しかしそもそも、正確な情報を返すのは、「開発の効率化」や「ユーザー体験の向上」のためにあるので、逆に問題が発生する可能性がある場合は、正確な情報を返す必要性は低い。

もちろん正確な情報はデバックや問題解決に役立つため、開発環境では正確な情報を返し、本番環境ではあえて曖昧な答えを返すといった対応も可能。
:::
Android Library を自作してJit pack に公開する時の備忘録

## 概要

Android Library を自作してJit pack に公開する時に遭遇した
エラーなどを備忘録的に残しておきたいと思います。


## 基本的な流れ

https://qiita.com/takagimeow/items/a62ba44c11117740c018#%E3%81%BE%E3%81%A8%E3%82%81

こちらの神記事をフォローします。

## いくつかの変更点と備忘録

ただ、いくつか変更した箇所がありました。

### build.gradle.kts

私の場合、build.gradle でなく、
build.gradle.kts (kotlin) を使っていたので、
app レベルのbuild.gradle.kts には

```build.gradle
afterEvaluate {
    publishing {
        publications {
            // Creates a Maven publication called "release".
            release(MavenPublication) {
                from components.release
                groupId = 'com.github.xxx'
                artifactId = 'xxx-yyy-zzz'
                version = '0.0.1'
            }
        }
    }
}
```

から、

```build.gradle.kts
afterEvaluate {
    publishing {
        publications {
            create<MavenPublication>("release") {
                from(components["release"])

                groupId = "com.github.xxx"
                artifactId = "xxx-yyy-zzz"
                version = "0.0.1"
            }
        }
    }
}
```

というふうにフォーマットを書き換える必要がありました。



### jitpack.yml

jitpack.yml に


```jitpack.yml
jdk:
  - openjdk11
```

と最初記載していましたが、


```bash
* What went wrong:
An exception occurred applying plugin request [id: 'com.android.application']
> Failed to apply plugin 'com.android.internal.application'.
   > Android Gradle plugin requires Java 17 to run. You are currently using Java 11.
```

というビルドエラーがjit pack で出たため、

```jitpack.yml
jdk:
  - openjdk17
```

とjdkのバージョンを調整しました。
wslでelixir その83

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
練習問題、やってみた。

# 練習問題
livebookで、BVHプレーヤーを実装せよ。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/adf74e67-6991-4afa-1431-f7e7e4da7527.png)

# サンプルコード

```
defmodule KinoThree.BVH do
  use Kino.JS

  def new(url) do
    Kino.JS.new(__MODULE__, url)
  end

  asset "main.js" do
    """
    import "https://unpkg.com/three@0.127.0/build/three.js";
    import "https://unpkg.com/three@0.127.0/examples/js/loaders/GLTFLoader.js";
    import "https://unpkg.com/three@0.127.0/examples/js/loaders/BVHLoader.js";
    export function init(ctx, url) {
    	const canvas = document.createElement("canvas");
    	ctx.root.appendChild(canvas);
    	const renderer = new THREE.WebGLRenderer({
    		canvas: canvas
    	});
    	const width = 500;
    	const height = 400;
    	renderer.setSize(width, height);
    	const scene = new THREE.Scene();
    	const clock = new THREE.Clock();
        let camera, 
         mixer, 
         skeletonHelper;
        const loader = new THREE.BVHLoader();
        loader.load(url, function(result) {
         skeletonHelper = new THREE.SkeletonHelper(result.skeleton.bones[0]);
         skeletonHelper.skeleton = result.skeleton;
         const boneContainer = new THREE.Group();
         boneContainer.add(result.skeleton.bones[0]);
         scene.add(skeletonHelper);
         scene.add(boneContainer);
         mixer = new THREE.AnimationMixer(skeletonHelper);
         mixer.clipAction(result.clip).setEffectiveWeight(1.0).play();
        });
       camera = new THREE.PerspectiveCamera(60, 500 / 400, 1, 1000);
       camera.position.set(0, 100, 300);
       scene.background = new THREE.Color(0xeeeeee);
       scene.add(new THREE.GridHelper(400, 10));
        function tick() {
         requestAnimationFrame(tick);
         const delta = clock.getDelta();
         if (mixer) 
          mixer.update(delta);
         renderer.render(scene, camera);
        }
        tick();
    }
    """
  end
end

KinoThree.BVH.new(
  "https://cdn.rawgit.com/perfume-dev/example-max/3f383158/example-bvh/A_test.bvh"
)
```


以上。
wslでelixir その82

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
練習問題、やってみた。

# 練習問題
livebookで、VRMビュワーを実装せよ。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/ad78c2b1-1a6f-3cd0-6f86-9546e37ffaf9.png)

# サンプルコード

```
defmodule KinoThree.VRM do
  use Kino.JS

  def new(url) do
    Kino.JS.new(__MODULE__, url)
  end

  asset "main.js" do
    """
    import "https://unpkg.com/three@0.127.0/build/three.js";
      import "https://unpkg.com/three@0.127.0/examples/js/loaders/GLTFLoader.js";
      import "https://unpkg.com/three@0.127.0/examples/js/controls/OrbitControls.js";
      import "https://unpkg.com/three@0.127.0/examples/js/loaders/BVHLoader.js";
      import "https://www.unpkg.com/@pixiv/three-vrm@0.3.6/lib/three-vrm.js";
      export function init(ctx, url) {
    	const canvas = document.createElement("canvas");
    	ctx.root.appendChild(canvas);
    	const renderer = new THREE.WebGLRenderer({
    		canvas: canvas
    	});
    	const width = 320;
    	const height = 320;
    	renderer.setSize(width, height);
    	const scene = new THREE.Scene();
    	const camera = new THREE.PerspectiveCamera(35, 500 / 400, 0.1, 1000)
        camera.position.set(0, 1.2, -1.9)
        camera.rotation.set(0, Math.PI, 0)
        const directionalLight = new THREE.DirectionalLight('#ffffff', 1)
        directionalLight.position.set(1, 1, 1)
        scene.add(directionalLight)
        const loader = new THREE.GLTFLoader();
        loader.load(url, (gltf) => {
        THREE.VRM.from(gltf).then((vrm) => {
    	    scene.add(vrm.scene);
        });
       },
       (progress) => console.log('Loading model...', 100.0 * (progress.loaded / progress.total), '%'),
       (error) => console.error(error))
        function tick() {
         requestAnimationFrame(tick)
         renderer.render(scene, camera)
        }
        tick();
    }
    """
  end
end

KinoThree.VRM.new("https://drumath2237.github.io/three-vrm-test/models/undefined-chan-toon.vrm")
```


以上。
Rubyのプログラムを実行する際にオプションを指定して引数を渡す方法。【optparseの使い方]

optparseの使い方について自分なりにまとめてみました。

## はじめに

Rubyで作成したプログラムを実行する際に引数を渡して実行したい場合


``$ sample.rb hello``

のような形で実行するとプログラム内で配列ARGVで引数を使うことができます。
## optparseでオプションを指定する
上記のようなやり方の他、optparseという標準ライブラリを使うことで引数の前にオプションを指定して実行する方法があります。
``$ sample.rb -m hello``
みたいな感じです。``-m``がオプションになります。

### この方法を使うメリットとして
-  オプションによって引数が何を意味をするのかがわかりやすくなる。（バージョンを引数にしたい場合オプションを``-v``にするなど）
- 引数が複数ある場合、通常のやり方だと定義した順番に引数を記述しないといけないが、オプションで指定する場合、順番を気にしなくて良い。

### optparseの使用方法

以下利用方法になります。

#### 1. プログラム内にoptparseを読み込む
```
require 'optparse'
```
組み込みライブラリではないのでrequireで読み込む必要があります。
#### 2.optのインスタンスを作成する
```
opt = OptionParser.new
```

#### 3. 取り扱うオプションを指定する
```
opt.on('-a')
```

実際にこの時点までの記述に``p ARGV``を足したコード
```
require 'optparse'
opt = OptionParser.new
opt.on('-a')
p ARGV
```
をオプション指定して実行すると
```
sample.rb -a hello
# => ["-a", "hello"]
```
となり、``-m``がオプションとして扱われておらず、ARGVには``-m``と``hello``の二つの引数が渡されているような状態になっています。
ここから``-m``のオプションの部分を取り除いて、ARGV[0]=="hello"の状態にするには
#### 4. opt.parseでオプションを取り除く
```
opt.parse!(ARGV)
```
上記の記述でARGVはオプション``-m``を取り除いたあとの状態の配列になる
ちなみに``!``をつけないと破壊的メソッドにならないため、
ARGVの状態は変わらない。
上記の記述p ARGVの前に加えて実行すると
```
sample.rb -a hello
# => ["hello"]
```
となり、引数が正しい形で受け取ることができる。

これでオプションを指定してプログラムに引数を渡すことが可能になった。

### 補足

#### オプションが複数あるときに指定されたオプションの有無によってプログラムの処理を変えたい場合
```
opt.on('-a') {|v| p v}
```
という記述をするとブロックのvの中にオプションがあった場合true,無しで実行された場合nilが入る
オプションを複数使う場合には
``params = {}``などの空のハッシュを定義しておいて
```
opt.on('-a') {|v| params[:a] = v}
opt.on('-b') {|v| params[:b] = v}
opt.on('-c') {|v| params[:c] = v}
```
のように記述しておくと
各ハッシュの要素にキーに指定したオプションの有無が入るので
``if params[:a]``のように条件分岐などする際に利用できる。

#### オプションをロングバージョンでも指定できるようにする

バージョンを指定するようなオプションの場合``-v``などと指定することが多いと思うが、こういう場合に``--version``でも同じく指定できるようにしたいときは
```
opt.on('-v', '--version')
```
とすると``-v``と``--version``のどちらでも指定できるようになる。

### まとめ

以上になります。
自分なりに学習したことをまとめてみました。
間違っている部分がありましたら教えていただけると幸いです。

##### 参考
https://docs.ruby-lang.org/ja/latest/library/optparse.html
AWS開発初心者の備忘録

AWSの開発をしたことがない初心者の備忘録です。
柔軟な構成にできるのがメリットであり初心者にはデメリットになる部分だったので、何やかんや開発するまでの勉強法を備忘録として残します。

**【前提】**
・AWSの用語、代表的なサービスとその簡単な機能はある程度知識として持っておくと良いので、事前に[AWS 基礎知識]などでヒットしたサイトにざっと目を通すことをおすすめします。


## アカウント登録（無料枠をフル活用）

https://aws.amazon.com/jp/register-flow/


## ハンズオン１（EC2＋RDS）
この構成のハンズオンはどこにでもあるので自分がやりやすいものを実施。

https://catalog.us-east-1.prod.workshops.aws/workshops/47782ec0-8e8c-41e8-b873-9da91e822b36/ja-JP


## ハンズオン２（サーバレス）
各サービスの機能が文字で読んでもいまいち理解しきれない場合に、知りたいサービスを利用したハンズオン


・API Gateway＋Lambda＋DynamoDB

https://pages.awscloud.com/JAPAN-event-OE-Hands-on-for-Beginners-Serverless-1-2022-reg-event.html?trk=aws_introduction_page

・CloudFront＋S3

https://pages.awscloud.com/JAPAN-event-OE-Hands-on-for-Beginners-StaticWebsiteHosting-2022-reg-event.html?trk=aws_introduction_page

https://pages.awscloud.com/JAPAN-event-OE-Hands-on-for-Beginners-CF_WAF-2022-reg-event.html?trk=aws_introduction_page


・Amplify利用の開発

https://pages.awscloud.com/JAPAN-event-OE-Hands-on-for-Beginners-amplify-2022-reg-event.html?trk=aws_introduction_page


・SAM利用の開発

https://pages.awscloud.com/JAPAN-event-OE-Hands-on-for-Beginners-Serverless-2-2022-reg-event.html?trk=aws_introduction_page


## 他
・[サービス名 ハンズオン][サービス名 使ってみた]などで検索してできそうなものを実施。
・ローカルでの開発も考える（Lambda利用するならローカルでLambdaのテストを行う環境をどう準備するか）。
・AWS Certified Cloud Practitionerの勉強がちゃんと役立つ。

https://aws.amazon.com/jp/certification/certified-cloud-practitioner/
キャッシュを利用したデータ取得をSWRで簡単に行う

## 今回のゴール

JsonplaceholderにあるデータをSWRライブラリを用いて取得する。

### 今回使用するJsonplaceholderのURL

```bash
https://jsonplaceholder.typicode.com/posts
```

### 公式HP

[データ取得のための React Hooks ライブラリ – SWR](https://swr.vercel.app/ja)

### 実践

下記で使用するHeaderコンポーネントは記述がありますが、本記事の内容とは関係ないので無視で構いません。

公式のデータ取得の欄によると、fetcherという定数を定義します。

```tsx
const fetcher = (url: string) => fetch(url).then((res) => res.json());

```

次に`useSWR`をswrから読み込みます。第一引数には取得したいURLを記述、第二引数はfeacherを代入します。そして、公式ページに記述があるように分割代入で、取得したデータを下記のように取得して代入します。

```tsx
  const { data, error, isLoading } = useSWR(
    'https://jsonplaceholder.typicode.com/posts',
    fetcher
  );
```

そして、下記の記述をすることで状態に応じた出力をすることができる。ローディングしているときはif文でのisLoadingの部分が表示される。エラーの場合は、if文のErrorの部分が表示される。

```tsx
const Contact = () => {

  const { data, error, isLoading } = useSWR(
    'https://jsonplaceholder.typicode.com/posts',
    fetcher
  );

console.log(data)

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error...</div>;
  return (
    <div>
      <Header />
    </div>
  );
};

export default Contact;
```

コンソールで取得したデータが出力されると思います。
Power AppsのShare point リスト作成の注意点

Power Appsでアプリを作るもっとも簡単な手段の一つが「Share point Listを作り外部データとして利用してキャンバスアプリを自動で作成する」方法。

とても便利ですが、リスト作成時に気を付けていないと後々大変なことになる。

1.列の名前は英語名
　Listは列の内部名を持ちます。リストを使う分には気にならないですが、Power Appsは内部名を参照しています。最初に登録した列の名前を元に内部名を作成しますが、2バイト文字などはunicodeで作成され、それを参照する際にさらに手間が増えます。

試しに入力した結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476406/050ed249-cc49-cecb-b200-d5da0f8fd26a.png)
test	test
test1	test1
1test	_x0031_test
Test	Test0
TEST	TEST2
テスト	_x30c6__x30b9__x30c8_
tEst	tEst3
test_1	test_1

1.1.　最も良いのは英単語
　英単語を記入するとそのまま内部名になります。
1.2.　記号と数字は使える
　一部の記号は使える。キーボードから直接入力するタイプの記号。
1.3.　大文字は区別されない
　大文字を使っても区別されない。同じ単語と認識されると末尾に連番が付与される。
1.4.　冒頭の数字は避ける
　数字であっても、冒頭に使うとunicodeに変換される
1.5．　2バイト文字は当然ダメ
　unicodeだらけになります。

2.リストの名前に括弧を使わない
　リストの名前に括弧を付ける、例えば「管理リスト(練習)」という名前にすると、いろいろ大変なことになる。
まず半角括弧がなぜか全角に変換されます。そして文字列を引用符で囲う必要があります。こうするとテーブルとして引用出来て、列名などが半自動入力できます。そして認識されない。なぜか認識できなくなる。半角括弧が良くなかったのかもしれないが、正常に動かない。
トラブルの原因が分からないままリストの名前を括弧なしに変更し、最初からAppsでキャンバスアプリを作成すると普通に動きました。不要なトラブルに繋がるだけなので、括弧は使わないこと。
独自 root CA 証明書のインストール方法 (Ubuntu)

たぶん Debian でも同じじゃないかな。

## tl;dr

公式ドキュメント読もう。
https://ubuntu.com/server/docs/security-trust-store

```
$ sudo apt-get install -y ca-certificates
$ sudo cp local-ca.crt /usr/local/share/ca-certificates
$ sudo update-ca-certificates
```

## 置き場所について

- `/usr/share/ca-certificates` 以下 
  → `/etc/ca-certificates.conf` を編集して、ファイルを指定したあとで、`update-ca-certificates` する必要があるよ
- `/usr/local/share/ca-certificates` 以下
  → `update-ca-certificates` で自動的に取り込まれるよ

https://askubuntu.com/questions/1150090/usr-share-vs-usr-local-share-where-to-install-ca-certs
`security find-generic-password` でキーチェーンアクセスのGUI上から登録したパスワードが取得できなかった

# 概要
キーチェーンアクセスAppのGUI上から登録したパスワードが取得できなかった。
```zsh
$ security find-generic-password -a [アカウント名] -s [サービス名] -w
security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain.
```

# 対応
コマンドライン上からパスワードを再登録する。
```zsh
$ security add-generic-password -a [アカウント名] -s [サービス名] -w [パスワード]
```

再度取得してみる。
```zsh
$ security find-generic-password -a [アカウント名] -s [サービス名] -w
[パスワード]
```

取れた。
WSLで使いたい機能

# WSL を使い込んでだいぶ経つ

## WSLでなければならないこととは？

先日、だれかがWSL Ubuntu導入がらみでエラーが出ると発言。それを耳にしてしまった。
その原因は特定できなかった。

それがきっかけで果たしてWindowsにWSL導入する必要がある局面ってなんだろうかって考えてしまった。

# linux向けにしか提供されてないアプリ

Linux専用アプリなら、そうだよな。思いつくのは

- muttmua
- todotxt 
- コマンドラインからツイートする奴
- Opensoapみたいなシミュレーター？

### muttmua

[mutt](https://wiki.archlinux.jp/index.php/Mutt)
Alternative: sylpheed

### todotxt

[todotxt](http://todotxt.org/)
Alternative: todotxt.net

### tweet CLI

これについては、例の買収があったあとでも使えるのか動作検証してない。どうなったんだろうか？
Alternative: tweet from a browser.

### シミュレーター

シミュレーションは、やらない。というか外部のマシンに接続して実行するので、ローカルではやらない。

[Openfoam](https://zenn.dev/yoshikz/articles/ebb9e07ab34a89)

## 他には？

- グラフを描画するプロッター系もWindows版ある。
- お絵描き系は、インクスケープけど、Windows版ある。

### プログラム言語の

Pythonだってジュリアだって、Windows版ある。むしろc#とかは、Windows版の方がデフォルト。マイクロソフトが開発した言語だから。

### 動画related

- Smplayer 再生もWindows版ある。
- FFMpegもWindows版ある。というかパワーシェルだけど。
- yt-dlp

### office work related 

マイクロソフトオフィスがあるから、ワープロ、表計算なんかはそれで間に合う。winword, excelをパスワード保護つきで送ってくる人がいて、これだけは、Ubuntu‐Linuxだと対応できない。卒Windows OSできない理由の一つ。あと、docxでテンプレートを送ってきて、この様式準拠でお願いしますって言われることもある。テンプレートをLibreofficeなどで開いて、対応例のPDFファイルを眺めながら、微調整するってのは、やりたくないのが人情ってもの。エディターだってvscodeつかえばいいし。PandocもWindows版ある。nkfもWindows版ある。

### スライド作りは

パワポ好きな人はこれでやればいいし、嫌いなひとは Marpとかがある。これもWindows版ある。

### 数式処理

MaximaのWindows版ある。

### version control system

Gitは、Windows版だとGUIになっちゃう（？）ので、それを回避したければWSL Ubuntuに導入するのが無難かな?Windowsだと、拡張子だけのファイル名のファイル(e.g., `.gitignore`)つくるのが大ごとだから、それには, いいなあ。

## dockerはきっと該当するね

こいつのWindows版は、・・・デスクトップって奴だ。個人利用ならいまでも無料だけど、これは重たい。chocolateY経由でインストールしたけど、アップデート／アップグレードの数回に一回はエラーが出現する。これはツラミ分高い。Docker CE は Docker の Community Edition で、Linux で Docker を無料で使えるし・・

# Summary

WSLを使うことで、Windowsを単体で使うときよりも利便性が高まり、実現できることの幅も広がった例について教えてください。
nodebrewをインストールしてnpmコマンドを実行できるようにする

## Laravelで使用できるようにする

```
composer require laravel/breeze:^1.13 --dev

php artisan breeze:install

php artisan migrate

npm install

// 開発サーバー起動
npm run dev

// 本番用にファイル出力
npm run build 
```

#### npmコマンドが実行できない場合

下記のコマンドを実行
```
nodebrew ls
```



```
v20.8.0

current: none
```

`current: none`だと、npmが使用できないので、下記のコマンドを実行する
バージョンは適宜変更してほしい。

```
nodebrew use v20.8.0 
```

実行後確認
```
nodebrew ls   
```

```
v20.8.0

current: v20.8.0
```

下記のコマンドで、バージョン確認ができればOK
```
npm -v
```
ルーターからバスを出す

ルーターを改造していろいろバスを出して遊んでいます。

![IMG_20231012_082455.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/5743abb9-401d-a9d1-5d85-8fd5548fbe58.jpeg)

FONにはボードの端に未結線のGPIOが4本あるのでそこをSPIにしています。

下の白いIOのルーターは最初の頃のターゲットでLEDとプッシュSWでI2Cを出しています。

黒いIOのルーターはEthernet SwitchのLEDをI2Sにしています。このモジュールのSOCはGPIOに自由に機能をアサインできるので神です。入出力両方の機能がアサインできるのですが、FreeBSDでは出力のみ対応しています。I2Sの再生ではすべて出力なので、問題ありません。同じモジュールでSPDIFを出すものも作ってみました。I2Sは4本ですがSPDIFは1本で済みます。これで新潟精密のDAC(FN1241)を付けて、mp3のストリーミング(JazzSakura)をずっときいています。

コネクタは千石電商で買ってきたQIコネクタを使っています。圧着だけだと抜けてしまう事があるので、ちょっとハンダ付けしています。あまりたくさんハンダをつけるとハウジングに入らなくなるので注意が必要です。

逆ざし防止のためにVCCに赤い印を付けています。

GPIOのドライイブの能力か回路の問題かバッファを入れないと動かない事もあります。

奇しくもすべてAtheosのMIPS SOCです。

もちろんみんなFreeBSD/mips 12-STABLEです。

楽しいですよ。
AZ-104試験対策のまとめ「VM編②」

## はじめに
Microsoft Azure Administrator(AZ-104)合格に向けた勉強でまとめた内容を本記事では投稿しています。
試験範囲の内容を私が勉強していく中で、
・忘れてしまっていた内容
・他の知識と絡めて理解した方が良い内容
・Microsoft Learnの読解に苦戦した内容
などをできるだけ分かりやすく簡潔にまとめることを意識しています。
Azureの勉強を一から始め、AZ-104取得を目指している方の参考になれば幸いです。
※本記事の内容が必ず試験に出るわけではないこと、ご注意ください

## 試験対策のまとめ
### **Azure Spot Virtual Machines**
* 大幅にコストを削減して未使用の容量を使用可能
* Azureで容量の回復が必要になると通知30秒後にVMが停止される(同時に削除も可能)
* 利用可能な容量は、サイズ/リージョン/時刻などによって異なる
* SLAはない
* VMは容量または設定した最大価格に基づいて停止/削除可能
* 最適なワークロード
    - バッチ処理ジョブ
    - 開発/テスト環境
    - 大規模なコンピューティングワークロードなど

* 参考
    - https://learn.microsoft.com/ja-jp/azure/virtual-machines/spot-vms

## 次の試験対策のまとめ
* **AZ-104試験対策のまとめ「ネットワーク編①」**

https://qiita.com/fsd-jume/items/8d86ffb24b68577e4075

## 学習内容をまとめたページの一覧

https://qiita.com/fsd-jume/items/6eda24728c9c03c36bc3
アサーションと汎用テスト関数

# 1.はじめに
+ 学んだことを振り返るために記載
+ assertion(アサーション)についてイマイチ分からなかったので書く
+ [今週学ぶテーマはソフトウェアテスト](https://qiita.com/yuyas7/items/582e2d0daf2baa786e84)


# 2.本文

### 2.1.assertionとは
+ プログラムの条件が満たされているかチェックする文。
+ 通常、コードの一部で期待される結果と実際の結果を比較される。
もし、期待が満たされない結果が出たら例外やエラーが発生する。
+ assertionがTrueの場合は、普通の処理をする。
Falseの場合は、アサーションエラーが発生しプログラムがクラッシュする。
+ クラッシュすることによりエラーや例外を特定し防止するのに役立つ。

・例
```sample.py
import math
def squareRoot(x):
    assert (x > 0)
    return math.sqrt(x)
```
この例だとassert文のxの値が0より大きいかチェックし、小さいならプログラムがクラッシュする。
大きいなら平方根で計算され出力される。

+ 得られるメリット
・エラーや例外を早期に発見することができる。
・コードの可読性や保守性を高めることができる。

+ 主な用途
・デバッグ
・テスト
・コードの品質向上

### 2.2.汎用テスト関数とは
+ 目的
・テストケースの共通部分を抽象化
・コードの重複を削減
・テストの標準化
・効率的なテストスクリプトの管理
・特定のテストスクリプト内で特定のテストケースを作成及び実行するために再利用できる関数

```sample.py
# 汎用テスト関数　オプションとしてcallbackがある。
def equalAssertion(a,b, callback = None):
    equality = (a == b) if callback is None else callback(a, b)
    print(f"Comparing {str(a)} and {str(b)} ..."
        + ("They are equal." if equality else "Error, they are not equal."))
    # 等しくなければクラッシュする。
    assert equality
    return True

arr1 = [1,2,3,4,5]
arr2 = [5,4,3,2,1]
arr3 = [5,4,3,2,1]

# 副作用がないreverse
def reverse1(a, b):
    res = [i for i in b[::-1]]
    return a == res

# 副作用があるreverse
def reverse2(a, b):
    b.reverse()
    return a == b

# pass
equalAssertion(arr1, arr2, reverse1)

# pass　副作用で arr3 = [1,2,3,4,5]になっている
equalAssertion(arr1, arr3, reverse2)

# fail arr2 = [5,4,3,2,1], arr3 = [1,2,3,4,5]
equalAssertion(arr2, arr3)
```

# 3.所感
+ 汎用テスト関数は、家のブレーカーみたいに機能に異常があったら落ちるようなものだと思った。
・理由
ブレーカーは、一定のW以上で電気系統の機能の全ての機能をオフにすることができる。
汎用テスト関数は、特定の条件を満たさなかったらプログラムをクラッシュさせて機能の停止をする。

+ assertionをうまく活用できれば、探すのに手間がかかる論理エラーを発見とかできると思った。 

# ex.参考資料
+ ChatGPT-3.5
+ [Recursion](https://recursionist.io/)
【個人開発】 ChatGPTを使った今までにないAI辞書＆英文解析アプリを作ってみました


[AI辞書＆英文解析アプリ](https://dsyrn6sezafk4.cloudfront.net/)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115627/41595f68-1443-2d34-a72c-75ab13efbe48.png)

# 更新履歴
語根、接頭辞、接尾辞を出力するようにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115627/20e6bffc-23dc-6e20-0639-382e1ea0bec4.png)

# はじめに
皆さんはどのようにして英語を勉強していますか？:thinking:
私も長い間英語を学んできましたが、TOEICの点数がなかなか伸びずに悩んでいます。
そんな中、AIを使った学習方法を知り、新しい学習ツールの可能性を見つけ、それを形にしようと決心しました。

# AI辞書＆英文解析アプリとは？
このアプリは、ChatGPTを活用して英語の単語や文を深く解析し、学習者に適切な情報を提供するツールです。
英語学習の際の新しいお供として活用いただけます。

# 辞書機能
学びが記憶に残るためには、学習内容に興味や関心を持つことが大切です。このアプリでは、語源や川柳、さらには漫画のキャラクターを使った例文をAIが生成。これにより、楽しみながら効果的に単語を覚えることができます。

以下、単語「absent」を使ったサンプルです。

・基本辞書
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115627/7723bebf-0910-59e0-4c68-03a316042c05.png)

・コアイメージ、語源
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115627/9710c49e-d130-f741-4150-74b2c4287c33.png)

・語呂合わせ、川柳
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115627/1778a290-63bd-0009-6c50-d194a0179a94.png)
AIが作成しているのでセンスは無いかも。。。:sweat_smile:

・漫画のキャラクターやストーリーを使った例文作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115627/1dc3c515-adaa-38dc-28b4-3965b3d2f4d1.png)
一応、漫画はランダムにしているのですがNetflixでワンピースを公開してから、ワンピースを使った例文が多くなりました。

・有用サイト連携
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115627/cca295f0-3ac8-1df0-d750-2bc46bf8ae64.png)

# 英文解析機能
・スラッシュリーディング
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115627/94ec9cba-cfdf-8999-916a-b8567970bdad.png)
フレーズ単位で読みやすくします

・各単語の品詞と意味
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115627/3a6f2f6d-d706-a3f0-f666-6f19fe6475eb.png)

・英文説明
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115627/f83a77ef-ee2e-82a9-8778-9a2e8fa92b6c.png)

# 今後の展望
・ChatGPT4対応（今のところ、金額が高いので3.5を使用しています）
・英文解析の機能強化
・単語データベースの拡充
・独自ドメインの使用
・日本語以外の他言語対応
・デザインの改良

# まとめ
よかったら、AI辞書＆英文解析アプリを使って評価いただければ幸いです。:bow_tone1:
ESP32ソフトウェアシリアルで遊ぶ。(送信)(9600bps)(オリジナル)

x 参考

https://qiita.com/YuseiIto/items/ddc15a77fd7b57ffa757

x 各自、勝手に微調整してね!!





目的

カラー液晶の開発用のため
デバッグ用にソフトウェアシリアルを導入する

いろいろ
たぶん、細かい修正と
タイミングの調整だけでいける。
完成した。

![o_cop664.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/6a371fb7-a467-422f-48fc-abd8f9025f65.jpeg)




メインのプログラム

```c++:main.cpp


//SER_LB_9600_ESP32_1

#include <Arduino.h>

#include "SER_9600_ESP32_1.h"

//初期化
void setup()
{

  //シリアルの初期化
  pc.beginNS(9600);

} //setup


//メインループ
void loop()
{

  //データの表示
  pc.printNS("HELLO WORLD\r\n");
  
  delay(1000);

} //loop



```


SER_9600_ESP32_1.hのプログラム


```c++:SER_9600_ESP32_1.h



#ifndef TEST_H
#define TEST_H

//SER_9600_ESP32_1.h


#define TX1      23      // ?pin

//#define UART_DELAY  96   //  9600bps  NG
//#define UART_DELAY  97   //  9600bps  NG
//#define UART_DELAY  98   //  9600bps  NG
//#define UART_DELAY  99   //  9600bps  NG
//#define UART_DELAY 100   //  9600bps  NG 
//#define UART_DELAY 101   //  9600bps  OK 1
//#define UART_DELAY 102   //  9600bps  OK 2
//#define UART_DELAY 103   //  9600bps  OK 3
//#define UART_DELAY 104   //  9600bps  OK 4
#define UART_DELAY 105   //  9600bps  OK 5
//#define UART_DELAY 106   //  9600bps  OK 6
//#define UART_DELAY 107   //  9600bps  OK 7
//#define UART_DELAY 108   //  9600bps  OK 8
//#define UART_DELAY 109   //  9600bps  OK 9
//#define UART_DELAY 110   //  9600bps  NG
//#define UART_DELAY 111   //  9600bps  NG


//#define UART_DELAY 1000   //  9600bps ok E


#define DW   digitalWrite


//クラスの定義
struct _pc
{
  void beginNS(int sp);      //メソッドの宣言
  int  putcNS(char ch);      //メソッドの宣言
  int  printNS(char *str1);  //メソッドの宣言
};


//ポートをhiにする 初期化
//メソッドの定義
void _pc::beginNS(int sp)
{
  //ポートをhiにする初期化
  pinMode(TX1, OUTPUT);
  DW(TX1, HIGH);
}


//仮想シリアルへの一文字出力 9600bps
//メソッドの定義
int _pc::putcNS(char ch)
{
  DW(TX1, HIGH);

  DW(TX1, LOW);//START
  delayMicroseconds(UART_DELAY); //START BIT WAIT

  for (int ii = 0; ii < 8; ii++) {
    DW(TX1, (ch >> ii) & 1  );
    delayMicroseconds(UART_DELAY); //DATA 1-8BIT WAIT
  }//for

  DW(TX1, HIGH);//Stop
  delayMicroseconds(UART_DELAY); //StOP BIT WAIT

  return (0);
}


//文字列の表示
//メソッドの定義
int _pc::printNS(char *str1)
{
  //文字の中身がゼロか
  while (*str1) {

    //一文字出力
    putcNS(*str1 ++);

  } //while

  //戻り値
  return (0);
}


//実体の作成
_pc pc;


#endif



```
投稿一覧を任意の場所に表示させる

ページの下部に`posts/index`の投稿一覧を表示したい場合、通常は別の部分テンプレートを使用して、それを `button_presses/index` ページに組み込むことができます。以下のステップで実現できます。

1. まず、`app/views/button_presses` フォルダ内に `\_post.html.erb` という名前の部分テンプレートを作成します。この部分テンプレートは、各投稿を表示するためのコードを含む必要があります。

```erb
# app/views/button_presses/_post.html.erb

<tr>
  <td><%= post.title %></td>
  <td><%= post.content %></td>
</tr>
```

2. 次に、`app/views/button_presses/index.html.erb` ファイル内で、部分テンプレートをループして表示するコードを追加します。具体的には、`@posts` 変数を使用して投稿の一覧を取得し、部分テンプレートをループして表示します。以下はその例です：

```erb
# app/views/button_presses/index.html.erb

<h1 class="text-center">挑戦回数: <%= @button_press.count %></h1>
<div class="text-center">
  <div class="btn-group">
    <%= link_to 'プラス', increment_button_presses_path, method: :post, class: 'btn btn-primary btn-lg text-light' %>
    <%= link_to 'マイナス', decrement_button_presses_path, method: :post, class: "btn btn-lg btn-danger text-light" %>
  </div>
</div>

<h2>投稿一覧</h2>
<table>
  <thead>
    <tr>
      <th>Title</th>
      <th>Content</th>
    </tr>
  </thead>
  <tbody>
    <% @posts.each do |post| %>
      <%= render 'post', post: post %>
    <% end %>
  </tbody>
</table>
```

ここで、`render` メソッドを使用して `\_post.html.erb` 部分テンプレートを呼び出しています。

このようにすると、`button_presses/index` ページの下部に `posts/index` の投稿一覧を表示できます。部分テンプレートを使用することで、コードの再利用性と保守性が向上します。

`each` メソッドを呼び出すため`@posts` 変数は、`button_presses/index` アクション内で適切に設定されている必要があります。

確認すべき点：

1. `button_presses/index` アクション内で `@posts` 変数が適切に設定されていることを確認してください。投稿データを取得し、`@posts` に代入する必要があります。

2. `@posts` 変数をセットするコードがアクション内に存在しない場合、コントローラーで `@posts` を設定するためのコードを追加してください。例えば：

```ruby
# app/controllers/button_presses_controller.rb

def index
  @button_press = ButtonPress.all
  @posts = Post.all # または適切な投稿のクエリを実行する
end
```

この例では、`@posts` 変数を設定しています。投稿を取得するために、`Post.all` というクエリを使用しています

`@posts` 変数を設定したら、`button_presses/index` ビューで投稿をループして表示できるはずです。


もし投稿の一覧ビューに編集ボタンと削除ボタンを追加するには、各投稿ごとに対応するアクションをリンクまたはボタンとして表示する必要があります。

```
<%= link_to '編集', edit_post_path(post), class: 'btn btn-primary text-light' %>
<%= link_to '削除', post, method: :delete, data: { confirm: '本当に削除しますか?' }, class: 'btn btn-danger text-light' %>
```
画面にボタンを表示し、押した回数を記録する

増減ボタンを押した回数を画面に表示し、データベースに保存するために、Ruby on Railsアプリケーションを作成できます。以下にステップバイステップで説明します。

1. **Railsアプリケーションの作成**:

    ```bash
    rails new ButtonCounter
    cd ButtonCounter
    ```

2. **データベースの設定**:

   データベースには、ボタンが押された回数を格納するためのテーブルを作成する必要があります。例としてSQLiteを使用します。

   ```bash
   rails generate model ButtonPress count:integer
   rake db:migrate
   ```

3. **モデルの設定**:

   `app/models/button_press.rb` ファイルを開き、データベースのテーブルと関連づけます。

   ```ruby
   class ButtonPress < ApplicationRecord
   end
   ```

4. **コントローラの作成**:

   ボタンの押下回数を増加させるためのコントローラを作成します。

   ```bash
   rails generate controller ButtonPresses
   ```

   それから、`app/controllers/button_presses_controller.rb` ファイルを開き、以下のようにアクションを設定します。

```ruby
class ButtonPressesController < ApplicationController
  def index
    @button_press = ButtonPress.first_or_create # 最初のレコードを作成または取得
  end

  def increment
    @button_press = ButtonPress.first_or_create # 最初のレコードを作成または取得
    @button_press.count = 0 if @button_press.count.nil? # count プロパティが nil の場合は初期化
    @button_press.count += 1
    @button_press.save
    redirect_to button_presses_path
  end

  def decrement
    @button_press = ButtonPress.first_or_create
    @button_press.count = 0 if @button_press.count.nil?
    @button_press.count -= 1 # 数を減らす
    @button_press.count = 0 if @button_press.count < 0 # カウントが負の値にならないようにする
    @button_press.save
    redirect_to button_presses_path
  end

end
```

5. **ビューの作成**:

   `app/views/button_presses` ディレクトリ内にビューを作成します。

   - `index.html.erb`:

```html
   <h1>Button Counter</h1>
   <p>Button pressed: <%= @button_press.count %></p>
   <%= link_to 'プラス', increment_button_presses_path, method: :post %>
　　　　　　<%= link_to 'マイナス', decrement_button_presses_path, method: :post　%>
```

6. **ルーティングの設定**:

   `config/routes.rb` ファイルを開き、以下のようにルーティングを設定します。

   ```ruby
   Rails.application.routes.draw do
     resources :button_presses, only: [:index] do
        post :increment, on: :collection
        post 'decrement', on: :collection
     end
     root to: 'button_presses#index'
   end
   ```

7. **サーバーの起動**:

   アプリケーションを起動します。

   ```bash
   rails server
   ```

8. **アプリケーションの動作**:

   ブラウザで `http://localhost:3000` にアクセスし、ボタンを押すとカウントが増加し、その回数が表示されます。

これにより、ボタンを押した回数を画面に表示し、データベースに保存するシンプルなRailsアプリケーションが完成します。
Figma - レスポンシブデザイン : パソコン版デザイン(2023/10/11)

2023/10/11 レスポンシブデザイン実践 : パソコン版デザイン

「レスポンシブデザインの考え方」
・パソコン / スマホどちらを優先するか
　↪︎用途に合わせて判断。

１.フレーム作成 - W:1800px
２.レイアウトグリッド
	- 列数12,コンテンツW:1300
	- Shift + R 定規の表示
	- コンテンツW:1300に定規ガイドを合わせ、幅余白を設定
	- 「ガター」グリッド線の間のライン
3. ヘッダーデザイン -優先度を考慮
	- 優先度(ゴールの設定)
	- ヘッダー画像を設置
	- ハンバーガーメニューはラインツール、長方形ツール
	- メインカラーの登録
	- Command + D 同じ動作の繰り返し
	- 「塗り」の透明度設定→「I」スポイトで透明度込みのカラー抽出

 4. メインビジュアル
	- 長方形ツールを使用
 5. コンポーネントを使用したグローバルナビ
	- アイコンをコンポーネント化「icon / setsumeikai」
	- セクション作成「コンポーネント」

 6. 横スクロールオブジェクト
	- 長方形設置
	- セクションタイトル
	- 黄金比 1:1.618
	- 「コンテンツを切り抜く」ボタン,
	(はみ出したコンテンツを表示させる)
	- Shift + H 画像の反転

 7.写真やテキストを綺麗に見せる
	- 写真,トリミング機能の活用
	- 自動カーニングの使用可否がフォントによる
 
8.入れ子のフレームによるレスポンシブ化
	-複雑な入れ子のフレームの使い方

9.優先度の高いバナーフレーム

10. フッターエリア、調整し易いリンクの作り方
11. 全体の調整
	-「メインコンポーネントに移動」ボタン
	- 外側のフレームをCommand + クリックで検索機能

12.美しいデザインにする為に
	- 配色をシンプルに
	- 文字は16pxが基本サイズ
	- 余計な装飾をなくし、余白でグループ分けを行う
	- 「デザインの4大原則」
	↪︎近接 : 関係する情報を近づける
	↪︎整列 : 要素に一体性を持たせる
	↪︎強弱 : 優先度をつけ、違いを明確にする
	↪︎反復 : 要素を繰り返すことで一貫性を持たせる

！強み … ジャケットデザイン、写真撮影の経験はウェブデザイン業務での画像素材の選定やレイアウトを組むバランス感覚に活かせそう。

———よく使うショートカット
・フレームの選択 … 「Command+クリック」 ・要素のコピー … 「option + コピー」 ・キーボード操作だとフレームインしない ・ショートカット ズームイン/アウト … 2本指 コピペ … Command + C,V 複製 … Command + D スタイルを引き継かずペースト … Command + Shift + V スタイルのみコピぺ … Comannd + Option + C / V 画面を動かす … Space + ドラッグ
拡大縮小 … K

———便利プラグイン
Font Viewer … フォント図録
iconify … SNSなど含むアイコンリスト
Hand Wireframe … フリーハンドのワイヤーフレーム
Unsplush … 写真素材
Better Font Picker … フォント
Insert Big Image … 大きい画像を非圧縮で配置
Contrast … コントラスト比を判定

uiGradients ... グラデーションライブラリ
Material Design Icons　... Googleが提供するアイコン素材集
fish shell argparse コマンドで未定義のオプションを読み飛ばす (ignore-unknown オプション)

fish shell の関数とfish shellの組み込み関数 `argparse` を組み合わせて, 既存のコマンドをラップしたコマンドを用意したいと思いました.

```
function checkupdates --description 'alias checkupdates=checkupdates'
    argparse --name=checkupdates 'j/json' -- $argv
    or return 1
    # 省略
```

オプション `-j` or `--json` だけを指定したときに限りこのラップ関数は機能しますが, 既存コマンド (`checkupdates`) の既存オプションを指定すると, エラーになってしまいます.

```
$ checkupdates -n --json
checkupdates: -n: unknown option
```

この場合, `argparse` コマンドのオプション `-i` or `--ignore-unknown` を指定することで回避できます.

```
argparse -i --name=checkupdates 'j/json' -- $argv
```

# 参考

https://fishshell.com/docs/current/cmds/argparse.html
WebAPIのエラーの表現について

## なぜエラーの表現方法を工夫するのか？
APIでは様々な状況でエラーを返す可能性がある。そこでエラーになった場合に、「エラーが発生しました」とだけ返すのはあまりにも不親切。なぜならクライアント側は何らかのエラーが発生したことは分かっても、「何が起こったのか？・どう対応するべきなのか？」が分からない。

**クライアントがAPIのレスポンスを元に、適切に問題を解決できるような情報を提供する必要がある**。（「使いづらいAPI」はクライアントが間違ったアクセスを大量に行い問題が発生してしまう危険性すらある。）

### 表現方法
#### ステータスコードで表現する
真っ先にやるべきことは、**適切なステータスコードを返すこと**。（ステータスコードごとの意味などは省略します。）

重要なポイントは、クライアントからのリクエストが成功した場合しか200番台のステータスコードを返してはならないという点。稀にデータとしてはエラー情報が返ってくるものの、ステータスコードは200を返すケースがあるが、汎用的なHTTPのクライアントライブラリには、ステータスコードを見てまずリクエストが成功したかどうか判断しているものが多く、エラーなのに200を返してしまうと、汎用的なエラー分岐が適切に利用できなくなる。


したがって、エラーは単にエラー情報をレスポンスボデイで返すだけでなく、まずは適切なステータスコードを返す必要がある。

#### エラーの詳細を返す
適切なステータスコードを返す一方で、ステータスコードは汎用的かつ一般的なもののため、個々のAPIの内容に関連したエラーを表現するには不十分。

例えば、404が返ってきても、「指定したデータそのものがなかった」のか、「エンドポイントが間違っていた」のかはステータスコードだけでは分からない。


そこでエラーの詳細な内容を返す方法は大きく2つある。
* HTTPのレスポンスヘッダに入れて返す方法
* レスポンスボディで返す方法

どちらの方法も返す情報は同じで、エラーの詳細コードと、その内容を人間が読める言葉で書いたメッセージなどを含む。

---
Excelのピボットテールで基本的な商品分析をする方法

仕事のために、特定の価格比較サイトからカメラ製品の情報を取得しました。初めての試みとして、630種類のデジタルカメラの詳細情報をExcelに入力することにしました。手作業だけでは困難だったため、保存していたHTMLファイルから必要なデータを抽出するために、Pythonの正規表現ライブラリ（re）を使用してHTML構造を解析しました。HTML解析には通常BeautifulSoupが使用されますが、大量のデータ（600KB）を処理する際にパフォーマンスの問題が発生したため、正規表現を使用することにしました。この作業には3日かかりましたが、すべての製品詳細データをExcelに格納することができました。

また、価格や売上の動向を把握するために、初めてピボットテーブルを使用しました。特に「おすすめのピボットテーブル」は視覚的に非常にわかりやすく、有用でした。


![スクリーンショット 2023-10-12 091856.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3245342/756b03dd-f695-a6f8-bbcc-33f523221f90.png)


初めてピボットテーブルを使用する際には、まず「おすすめのピボットテーブル」を選択し、作成します。フィールドリストから行ラベルに「メーカー名」、「商品名」、「新品価格」、「中古価格」をドラッグします。列ラベルには「売れ筋順位」と「ユーザーがこの製品をお気に入りに入れた人数」を表示します。フィルターを使用して、2013年以降に発売された製品に絞り込みます。

これにより、メーカー別に製品名が表示され、その右側に売れ筋順位とユーザーがお気に入りに入れた数が表示されます。さらに各製品をクリックすると、新品価格と中古価格が表示されます。これにより、売れ筋製品の相場を客観的なデータに基づいて分析することが可能となります。

Excelのピボットテーブルは強力な機能であり、データ分析のための重要なツールです。ぜひ活用してみてください。ご意見やご質問がありましたら、お気軽にコメントください。