OmniAICreator/Qiita-1.07M huggingface dataset:
【メモ】AWS ELB, CloudFront, Route53の違い



## ELB（Elastic Load Balancer）:

特徴:
ELBは、複数のバックエンドインスタンス（Amazon EC2インスタンス、コンテナ、IPアドレスなど）にトラフィックを分散するためのロードバランシングサービスです。
トラフィックの均等分散により、アプリケーションの冗長性と可用性が向上します。
自動的にスケーリングするため、トラフィックの変動に応じて自動的にインスタンスを追加または削除できます。

違い:
ELBはレイヤー4（トランスポート層）およびレイヤー7（アプリケーション層）のロードバランサです。トラフィックを分散するだけでなく、HTTP/HTTPSリクエストの解析やセッション固定などの高度な機能を提供します。
ELBは、Amazon EC2インスタンスにのみトラフィックを分散するのに対し、CloudFrontはより一般的なコンテンツデリバリーネットワーク（CDN）として機能します。

## CloudFront:

特徴:
CloudFrontは、コンテンツデリバリーネットワーク（CDN）サービスであり、高速でセキュアなコンテンツの配信を提供します。
オリジンサーバー（ウェブサーバー、S3バケットなど）からの静的および動的コンテンツをグローバルにキャッシュし、ユーザーに近いエッジロケーションからコンテンツを配信します。
ドメイン名のカスタマイズ、SSL/TLS証明書の統合、DDoS保護、アクセスコントロールなどの機能を提供します。

違い:
CloudFrontは、コンテンツの配信を最適化するためにキャッシュを使用し、グローバルなエッジロケーションでコンテンツを提供します。
一方、ELBは単にトラフィックを分散する役割を果たします。
CloudFrontは、スタティックおよびダイナミックコンテンツの両方を配信できる一方、ELBは主にアプリケーション層のトラフィックを分散するために使用されます。

## Route53:
特徴:
Route53は、AWSのマネージドDNS（Domain Name System）サービスです。
ドメイン名の登録、DNSレコードの管理、ドメインのルーティングなど、DNSに関連する機能を提供します。
ロードバランシングやフェイルオーバーなどのトラフィックルーティングポリシーをサポートしており、可用性とパフォーマンスの向上に役立ちます。

違い:
Route53は、ドメイン名と関連するDNSレコードの管理に特化しています。
ELBおよびCloudFrontは、トラフィックの分散やコンテンツの配信に特化していますが、Route53はDNSレベルのルーティングを提供します。
Route53は、ドメイン名の登録や管理、ドメインの健全性の監視、ドメインに関連するセキュリティ機能（DNSSECなど）など、DNSに関連する一連の機能を提供します。

## まとめ
ELBはアプリケーション層のロードバランシングに特化し、CloudFrontはコンテンツのグローバルな配信とキャッシュに特化しています。
一方、Route53はマネージドDNSサービスであり、ドメイン名とDNSレコードの管理、およびDNSレベルのトラフィックルーティングを担当しています。
Rails で N+1 を解消したいのに関連先が取れない

## やりたいこと
N+1 を解消するのには `includes` や `eager_load` 、 `preload` を使えばいいのは分かったしその違いも分かった。
でも、関連付けが取れない。

Author が books を has_many で book も reviews を has_many してるとき、普通に Author.books.reviews を取ったら N+1 になるじゃないですか。
だから以下のように書きたい。でも書けない。

```rb
Author.joins(:books).includes(:reviews)
```

みたいに書きたいんだけど、そうすると

```sh
ActiveRecord::AssociationNotFoundError: Association named 'reviews' was not found on Author; perhaps you misspelled it?
Did you mean? books
```

なんて感じのエラーになってしまう。
どう書けばいいんだろう？

## 正解

```rb
Author.includes(books: :reviews)
```
https://railsguides.jp/active_record_querying.html#%E3%83%8D%E3%82%B9%E3%83%88%E3%81%97%E3%81%9F%E9%96%A2%E9%80%A3%E4%BB%98%E3%81%91%E3%83%8F%E3%83%83%E3%82%B7%E3%83%A5

を見れば、複数の関連付けを取りたい場合なども分かります。
ヒックの法則

# ヒックの法則

ヒックの法則（Hick's law）とは、判断・決定するために必要な時間が、選択肢の数に比例して増加するという心理学の法則です。この法則は、1952年に心理学者のウィリアム・エドワード・ヒックによって提唱されました。

例えば、ある人が何かを注文するときに、メニューにある選択肢が多いと、どれを選べばいいのかを判断するのに時間がかかるということです。同様に、ウェブサイトのナビゲーションメニューが多く、目的のページにたどり着くのに複数のクリックが必要な場合、ユーザーは混乱しやすく、意思決定に時間がかかります。

この法則は、人間の認知に関する基本原理の一つであり、情報処理能力によって判断・決定の速度が変化するということを示しています。これは、情報処理において、人間の脳が一度に処理できる情報量に限りがあるためです。

ヒックの法則は、デザインや情報アーキテクチャに関する分野で重要な考え方となっており、情報の整理や選択肢の最適化に応用されます。例えば、ウェブサイトのナビゲーションメニューにおいては、選択肢を少なくすることでユーザーの意思決定を促進し、スムーズなサイト利用を実現することが求められます。

## 選択肢の最適化とは

ヒックの法則に基づき、意思決定を迅速かつ正確にするために、選択肢の数を最適化することを指します。選択肢の数が少なすぎると選択肢が限られ、選択肢の数が多すぎると意思決定に時間がかかるため、適切な選択肢の数を提供することが必要です。

例えば、ウェブサイトのメニュー設計において、選択肢の最適化は非常に重要です。ユーザーが目的のページに到達するために、メニューから複数のリンクをクリックする必要がある場合、選択肢の数が多すぎると、ユーザーがどのリンクをクリックするべきか迷いやすくなります。そのため、選択肢を絞り込んで、ユーザーが目的のページに素早くアクセスできるようにする必要があります。

選択肢の最適化には、以下のような方法があります。

1. カテゴリー分け：選択肢をいくつかのカテゴリーに分類し、ユーザーが目的の項目を見つけやすくする方法です。

1. サジェスチョン：ユーザーが入力したキーワードから関連する項目をサジェストする方法です。これにより、ユーザーは手動でリストを探す必要がなく、時間が短縮されます。

1. タブレスデザイン：ウェブページのタブを使用する代わりに、垂直のリストを使用する方法です。これにより、ユーザーは画面上で選択肢をすばやくスキャンできます。

1. ウィザード：一連の手順を通じて、ユーザーを目的の項目に導く方法です。これにより、ユーザーは自分がどこにいるのか理解しやすくなります。

これらの方法は、選択肢の最適化を行うための基本的なアプローチです。選択肢の最適化により、ユーザーはスムーズで効率的なウェブサイトの利用が可能になります。
最短時間の経路をスネルの法則を使って求める

### 最短時間の経路問題

以下の図で6km離れたA点からB点に移動したいが、間に幅1km砂利が敷き詰められた場所がある。普通の道は時速6km/hで歩けるが砂利のところは4km/hになる。最短移動時間を求めよ.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1922159/581693f9-a254-ffbb-1e6e-7993ad119b15.png)

この砂利が無ければ1時間で移動できますが。まっすぐ進んだ場合砂利の部分の長さは$w=\sqrt{2}$kmなので移動時間$t$は以下のようになります。これが経路を変えると短くなるのかという問題です。

```math
t = (6-w)/6 + w/4 = 1.118
```

### スネルの法則

以下のリンクを参考すると分かるようにスネルの法則は光の屈折率を求める公式ですが、その屈折率に沿った経路が**最短時間**となることが証明されています。

> [スネルの法則をフェルマーの原理を用いて証明](https://manabitimes.jp/math/955)


そこで以下のスネルの法則に基づいて境界で経路を曲げて最後にゴールのB点に到達するような"入射角"をBinary Searchで求めるようなプログラムを書きました。

入射前/後の速度を$v_1$/$v_2$とすると入射/出射角$t_1/t_2$の関係

```math
\frac{\sin t_1}{\sin t_2} = \frac{v_1}{v_2} 
```

```python 
from math import sqrt, sin, asin, cos, pi, radians, degrees, tan
L = 6   # direct distance
W = 1   # marsh width
s = [6, 4, 6]  # Speed of walk in each strip
Xab  = L/sqrt(2)
w0 = (Xab-W)/2
w = [w0, W, w0]  # width of each strip

def refract(deg):  # return x-final position, travel time
  t1 = radians(deg)
  xsum, ttime = 0, 0 
  for i in range(len(s)):
    xsum += w[i]* tan(t1)          # x position accumulative
    ttime += (w[i]/cos(t1)) / s[i] # travel time
    if i == len(s)-1: break
    t1 = asin(s[i+1]*sin(t1)/s[i]) # next refraction angle
  return xsum, ttime

# Binary search to find target xsum from initial angle
d1, d2 = 45, 70   # 
while True:
  dc = (d1+d2)/2
  xsum, ttime = refract(dc)
  if abs(Xab-xsum) < 10**(-5): break  
  if xsum < Xab:
    d1 = dc
  else: 
    d2 = dc

print(f"Answer: {ttime:.03f}, angle = {dc:.1f}")
# Answer: 1.104, angle = 48.5
```

このように最初の入射角を48.5度にすることで移動時間が短縮されたことが分かります。

| |最短移動時間 | 最初の入射角 |
|:---:|:---:|:---:|
| 砂利が無ければ|1時間 | 45度　| 
| 砂利も含めてまっすぐ|1.118時間 |45度　| 
| 最短時間経路|1.104時間 |48.5度　| 

（開発環境：Google Colab）

この問題はProject Euler Problem 607: Marsh Crossingを解くのに役に立ちます。
Goプロジェクトの作成〜サーバーへのアクセスまで

APIやらバッチやらなんだかんだGoは1年半以上書いていますが、
Goのサーバは0ベースで書いたことないなと思い、簡単に立ててみようかなと。

## 作成手順

### リポジトリの取得

リポジトリのClone。

```shell
$ git clone git@github.com:mitsuaki1229/GoServerExample.git
```

```shell
$ cd GoServerExample
```

### サーバの作成

mainの作成。

```shell
$ touch main.go
$ vim main.go
```

[echo](https://echo.labstack.com/)でサーバの中身の記載。

```shell
package main

import (
	"net/http"

	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"
)

var e = createMux()

func main() {
	e.GET("/", articleIndex)

	e.Logger.Fatal(e.Start(":8080"))
}

func createMux() *echo.Echo {
	e := echo.New()

	e.Use(middleware.Recover())
	e.Use(middleware.Logger())
	e.Use(middleware.Gzip())

	return e
}

func articleIndex(c echo.Context) error {
	return c.String(http.StatusOK, "Hello, World!")
}
```

### プロジェクトの初期化

パスを指定しないとエラーになる。

```shell
$ go mod init
go: cannot determine module path for source directory /Users/mitsuaki1229/Documents/90_Other/repo/GoServerExample (outside GOPATH, module path must be specified)
```

GitHubのパスを指定して再実行。

```shell
$ go mod init github.com/mitsuaki1229/GoServerExample
go: creating new go.mod: module github.com/mitsuaki1229/GoServerExample
go: to add module requirements and sums:
	go mod tidy
```

モジュールのインポート。

```shell
$ go mod tidy
go: finding module for package github.com/labstack/echo/v4/middleware
go: finding module for package github.com/labstack/echo/v4
go: downloading github.com/labstack/echo/v4 v4.10.2
go: downloading github.com/labstack/echo v3.3.10+incompatible
go: found github.com/labstack/echo/v4 in github.com/labstack/echo/v4 v4.10.2
go: found github.com/labstack/echo/v4/middleware in github.com/labstack/echo/v4 v4.10.2
go: downloading github.com/labstack/gommon v0.4.0
go: downloading golang.org/x/crypto v0.6.0
go: downloading golang.org/x/net v0.7.0
go: downloading github.com/stretchr/testify v1.8.1
go: downloading github.com/valyala/fasttemplate v1.2.2
go: downloading golang.org/x/time v0.3.0
go: downloading github.com/mattn/go-colorable v0.1.13
go: downloading github.com/mattn/go-isatty v0.0.17
go: downloading gopkg.in/yaml.v3 v3.0.1
go: downloading github.com/valyala/bytebufferpool v1.0.0
go: downloading golang.org/x/text v0.7.0
go: downloading golang.org/x/sys v0.5.0
```

### 起動

```shell
$ go run main.go

   ____    __
  / __/___/ /  ___
 / _// __/ _ \/ _ \
/___/\__/_//_/\___/ v4.10.2
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
                                    O\
⇨ http server started on [::]:8080
```

### アクセス確認

http://localhost:8080/

![Screen Shot 2023-05-29 at 20.53.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25578/a5f55dab-55e4-20ab-a7b3-bc29fbdc8ba6.png)

## 感想

[Spring Boot](https://spring.io/projects/spring-boot)や[Ruby on Rails](https://rubyonrails.org/)と比べると、シンプルに出来るのが良いですね。

## 参考

* [1-3Web サーバーを起動しよう](https://www.techpit.jp/courses/29/curriculums/30/sections/256/parts/876)

## 参照

* [GoServerExample](https://github.com/mitsuaki1229/GoServerExample)
symfony プロジェクトに新しく controller を定義する（routingとviewも併せて）

本記事は以下の環境で動作確認します。

```
OS: macOS Venture 13.3.1
Chip: Apple M1 Pro
```

前提として、`symfony` アプリケーションは構築済み。: `version 5.4`

https://qiita.com/shota_tanaka/items/e9465be2986fe9482e87

controllerの定義ついでに、以下も行います。
- routing定義を`annotation`でおこなう。
- viewを`twig`というテンプレートエンジンで描画。
### controller の定義

[公式ドキュメント](https://symfony.com/doc/5.4/page_creation.html#creating-a-page-route-and-controller)に沿って、以下コントローラを定義: `src/Controller/LuckyController.php`
```php
namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;

class LuckyController
{
    public function number(): Response
    {
        $number = random_int(0, 100);

        return new Response(
            '<html><body>Lucky number: '.$number.'</body></html>'
        );
    }
}
```

### viewをtwigで定義
レスポンスオブジェクトをそのまま返却ではなく、twigテンプレートエンジンで描画して返却するよう修正。

[公式ドキュメント](https://symfony.com/doc/5.4/page_creation.html#rendering-a-template) に沿って`twig`のインストール
```shell
symfony composer require twig
```

`twig`でレンダリングするためには、`AbstractController`を継承する必要があるのでその修正も実施。
```diff
namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;
+ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

- class LuckyController
+ class LuckyController extends AbstractController
{
    public function number(): Response
    {
        $number = random_int(0, 100);

-        return new Response(
-            '<html><body>Lucky number: '.$number.'</body></html>'
-        );

+        return $this->render('lucky/number.html.twig', [
+            'number' => $number,
+        ]);
    }
}
```

twigファイルを作成。: `templates/lucky/number.html.twig`
```twig
<h1>Your lucky number is {{ number }}</h1>
```


### routingをannotationで定義
通常であれば`yaml`ファイルで定義するところ、annotation（注釈）で各アクションに対するルーティング定義ができるのでそちらを採用。

[公式ドキュメント](https://symfony.com/doc/5.4/routing.html#creating-routes-as-attributes-or-annotations)に沿って、`doctrine/annotations`をインストール。
```shell
symfony composer require doctrine/annotations
```
annotationを追記。

```diff
namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;
+ use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class LuckyController extends AbstractController
{
+    /**
+     * @Route("/lucky/number", name="app_lucky_number")
+     */
    public function number(): Response
    {
        $number = random_int(0, 100);

        return $this->render('lucky/number.html.twig', [
            'number' => $number,
        ]);
    }
}
```

### 動作確認

```shell
symfony php bin/console debug:router app_lucky_number
```
|  Property  |  Value  |
| ---- | ---- |
|  Route Name  |  app_lucky_number   |
|  Path  |  /lucky/number    |


[https://127.0.0.1:8000/lucky/number](https://127.0.0.1:8000/lucky/number)
【Python】大規模データのCSVファイルのレコード数（行数）を一瞬でカウントする方法

# 概要
* 大量のデータを扱う仕事をしていると、エクセルでは表示しきれない場合や重すぎて開くのが大変という場合がありますよね。そんな大規模データの件数をすぐに調べられる方法を紹介します。

## 発生エラー
* エクセルは、行数が1,048,756行に達すると表示が停止します。また、非常に操作が重くなります。    
    * 使用しているExcelは、Excel for Macのバージョン16.73(2023のバージョン)

```
このテキスト ファイルのデータは、1 つのワークシートに入りきりません。
```

* MacのNumberでは開くと以下のエラーが出てきます。

```
Nubmersの表では1,000,000を超える行をサポートできません。一部の内容は読み込まれせんでした。
```

* くぅぅ、行数を見たいだけなのに全然させてくれん！！こんな時こそプログラミング！

# 解決方法

* 今回は、pythonでCSVファイルの行数をカウントする方法を紹介します（違う言語でもできるはずです）。

```count.py
import csv

def count_csv_rows(file_path):
    with open(file_path, 'r') as file:
        reader = csv.reader(file)
        row_count = sum(1 for row in reader)
    return row_count

file_path = 'data_file.csv'  # CSVファイルのパスを指定
row_count = count_csv_rows(file_path)
print("行数:", row_count)
```

* `data_file.csv`にはファイルがあるパスを指定します。このPythonファイルと同じ場所にあれば、ファイル名だけでOKです。
* 以下の内容を実施しています。
    * `csv`モジュールを使用してCSVファイルを開き、`csv.reader`オブジェクトを作成。
    * `sum(1 for row in reader)`の部分は、ジェネレータ式を使って各行ごとに`1`をカウントし、その合計を取得。
* あとは、`python count.py`を実施すれば、以下のように出力されます。

```
行数: 1781695
```

* ついでに、CSVファイルにはヘッダーがあるよ、という場合は以下を実施するとすぐに算出できます。

```python
import csv

def count_csv_records(file_path):
    with open(file_path, 'r') as file:
        reader = csv.reader(file)
        header = next(reader)  # ヘッダー行を読み飛ばす
        record_count = sum(1 for row in reader)
    return record_count

file_path = 'data_file.csv'  # CSVファイルのパスを指定してください
record_count = count_csv_records(file_path)
print("レコード数:", record_count)
```

* すると以下のような結果になります。

```
レコード数: 1781694
```

* Pythonを実行するにはPythonのインストールが必要ですが、一瞬で出てくるのでかなり楽ですよね。
Python100問パックやってみた

今回は以前購入したはやたすさんのPython演習100問パックをやってみた。

先週の月曜日から木曜日までやってひとまず50問まで終了した。
分かりそうで全然間違えている問題とか、調べて書いたら当たってたりとか、そもそも全然分からなくてギブアップした問題とかが多かった。

自分の解答→答えの解答→説明をメモる
このループだった。

有料なので内容は書けないけど「Google Colab」を使った演習になっていて、使い方がイマイチ分かってなかったのでそれの使い方をやりながら慣らしていけるのでけっこうありがたい。

でも50問やった中でもリスト型が特に難しかった。ここは要復習ポイント。

今週中には100問完走できると思うので、終了したらまた2周目、3周目をしていこうと思う。（超魔界村みある）
stringをenumに変換する便利クラス

## \| 概要
よく使うし、Extensionで実装することが多かったので
このスクリプトだけ入れておけばOKなものを作った。
中身はTryParseしているだけのつくり。特に解説はない。

## \| ソースコード全文
EnumParser.cs
```csharp
using System;

/// <summary>
/// Enumのパース用
/// </summary>
public static class EnumParser
{
    public static T Parse<T>(string value) where T : struct, Enum
    {
        T result;
        if (!Enum.TryParse(value, true, out result))
        {
            throw new ArgumentException($"'{value}' is not a valid value for {typeof(T).Name}.");
        }
        return result;
    }
}
```

## \| 使用例
```csharp
using System;

enum WeaponType
{
    Sword,
    Spear,
    Axe,
}
void Func(string _weaponType)
{
    WeaponType weapon = EnumParser.Parse<WeaponType>(_weaponType);
}
```
pythonでYahoo Financeしてみた

# 以下のような株アプリを作ってる

https://stonehills.tokyo/financer/

# yfinanceのインストール
yfinanceはpythonのでYahoo Financeにアクセスするためのライブラリです。個人利用しか出来ないです。

https://stonehills.tokyo/stockinvest/index.php/python_yahoo

pipをインストールして、yahoo finance ライブラリをインストールします。
```
   # apt install pip
   # pip install yfinance
```

# テーブル作成
json型を使います。

```
    create database finance;
    CREATE USER 'finance'@'localhost' IDENTIFIED BY 'xxxxx';
    GRANT ALL PRIVILEGES ON * . * TO 'finance'@'localhost';
    use finance;
    CREATE TABLE YahooFINANCE (
      t_date date NOT NULL,
      ticker VARCHAR(255) NOT NULL,
      attr JSON,
      CHECK (JSON_VALID(attr)),
      PRIMARY KEY (t_date,ticker)
   );
```

# GOOGLEの情報をデータベースにinsertし、selectするpy

```
import mysql.connector
import yfinance as yf
import json

ticker = yf.Ticker("GOOG")

conn = mysql.connector.connect(
    user="finance",
    password="xxxxx",
    host="localhost",
    database="finance")
cur = conn.cursor() 

sql = ('INSERT INTO YahooFINANCE (t_date, ticker, attr) VALUES (now(6), %s, %s) ON DUPLICATE KEY UPDATE attr = VALUES (attr);')

data = [
     ('GOOG', json.dumps(ticker.info)) 
]

cur.executemany(sql, data)

conn.commit() 

cur.execute("SELECT t_date,ticker FROM YahooFINANCE", ()) 

for id,ticker in cur: 
    print(f"TICKER: {ticker}, ID: {id}")

conn.commit() 
```
在宅用NPPVのFiO2計算について

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">「<br>【訂正再掲】 患者さんに在宅用NPPVを導入したところ、1回換気量が400ml、吸気立ち上がり時間が0.6秒でした。側管から流す酸素を3.0L/minにしました。<br><br>Q1, このときの推定FiO2を求めなさい<br>Q2, FiO2=0.40のときに必要な酸素流量を求めなさい。<br>」<br><br>前回、レスポンスがなかったので再掲。</p>&mdash; 楊 泰(よう やすし)@目指せ医者エンジニア🩺🐧💦 (@Yoh_Yasushi) <a href="https://twitter.com/Yoh_Yasushi/status/1661347375674462208?ref_src=twsrc%5Etfw">May 24, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

**Q1, このときの推定FiO2を求めなさい**

上記のツイートに対しての回答を記載します。


まず患者の分時換気量を求めましょう。

400mlを0.6秒で吸気しているので、その時の流量は、

```
( 400 / 0.6 ) * 60 /1000 = 40.0
```

より、`40.0L/min` となります。

ここで重要なのは、**この流量は空気も側管から流す純酸素も合わせたものになる**、ということです。ので側管から流れる酸素流量が増えたら、空気の流入はその分減ります。この点は非常に重要です。

あと、呼気の再吸気とかは無い前提で話をすすめます。

となると↓のようになりますね。単位は`L/min`とします。

| 空気 | 純酸素 | 
|-----|-----:|
| 40  | 0  |
| 39  | 1  |
| 38  | 2  |
| 37  | 3  | 

(以下続く)

となりますね、わかりますか？そして空気の`FiO2`は当然`0.21`ですから、求めたい`FiO2`は、


````
((37 * 0.21) + ( 3 * 1.00)) / 40 = 0.26925 
````

よって四捨五入して、「**0.27**」が答えです。


**Q2, FiO2=0.40のときに必要な酸素流量を求めなさい。**

この問題を解くためにはQ1で用いた式を記号に置き換えた上で、式変形をする必要がありますね。

| 空気 | 純酸素 | 
|-----|-----:|
| M | 流量  |
| X | 酸素流量 |
| F | FiO2 |

と置くと、下のようになりますね。

```
((M - X) * 0.21 + ( X * 1.00 )) / M = F
```

これをXを左辺において式変形すると、

```

X = ((M * F) - ( 0.21 * M )) /0.79

```

右辺に`M = 40` 、 `F as FiO2 = 0.40`を代入すると、

```
X ≒ 9.620 
```
となり、正解は、「**9.6 L／min**」ですね。


**まとめ**

何が言いたいかというと、*在宅用NPPVでFiO2を上げるのには大量の酸素が要る*ということなんです。

この計算ができるエクセルは以下のGitHub上に置いております。皆さん、ダウンロードしてご活用くださいませ。

[GitHub - YohYasushi/Rinsho_Excels](https://github.com/YohYasushi/Rinsho_Excels)
ReactJs Solved— Matched leaf route at location “/” does not have an element

Rails apiモードとReactでcreateページを作成する際にこのようなエラーが表示されたので、解決策を記述しておきます。

```shell
Matched leaf route at location "/" does not have an element or Component.
This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.
```


結論として、Routeの記述の仕方が間違っているということです。v6ではcomponentという記述は使えなくなっているようです。そのため、componentの部分をelementに修正してあげるとエラーが解決します。
```javascript
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
// import ReactDOM from "react-dom";
const App = () => {
  return (
    <Router >
      <Routes>
        <Route path="/" component={ Home }></Route>
      </Routes>
    </Router>
  )
}
export default App;
```


解決策
```javascript
<Route path="/" element={<Home />}></Route>
```
スタックを使用して、ひとつ前のシーンに戻る

ドラクエなどのRPGでよくあるフィールドマップと戦闘の切り替えに使えます。
応用すればUIの遷移も作れます。

まず、ひとつ前のシーンを保持する```SceneStack```クラスを作ります。
このとき、```ScriptableObject```を継承します。
ScriptableObjectは、シーンを読み込んでも変数の値を保持してくれるので、今回のケースに最適です。

```csharp
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

[CreateAssetMenu]
public class SceneStack : ScriptableObject
{
    private Stack<Scene> scenes = new Stack<Scene>();

    // シーンをスタックから取り出す
    public Scene Pop()
    {
        return scenes.Pop();
    }

    // シーンをスタックに積む
    public void Push(Scene scene)
    {
        scenes.Push(scene);
    }
}
```

つぎに、シーンをスタックに積んでから読み込むスクリプトを書きます。

```cshap
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneLoader : MonoBehaviour
{
    public SceneStack scenes;
    public SceneAsset scene;

    public void Load()
    {
        scenes.Push(SceneManager.GetActiveScene());
        SceneManager.LoadSceneAsync(scene.name);
    }
}
```

つぎに、ひとつ前のシーンに戻るスクリプトを書きます。

```csharp
using UnityEngine;
using UnityEngine.SceneManagement;

public class BackScene : MonoBehaviour
{
    public SceneStack scenes;

    public void Back()
    {
        var scene = scenes.Pop();
        SceneManager.LoadSceneAsync(scene.buildIndex);
    }
}
```

これらを組み合わせることで、ひとつ前のシーンに戻ることができます。
また、スタックにシーンを積んでいくので前の前のシーンに戻ることもできます。

今回はAddressableを使いませんでしたが、スタックの型を```AssetReference```にすることで対応可能です。
[AWS Q&A 365][SNS]AWSのよくある問題の毎日5選 #70

# 1. A2Pメッセージングとは何ですか？
A2Pメッセージングとは、Application-to-Person messagingの略で、アプリケーションから個々のモバイルデバイスにメッセージを送信するプロセスを指します。

# 2. A2Pメッセージングはどのように動作しますか？
A2Pメッセージングは、通常、APIを使用してメッセージングゲートウェイに接続し、その後、メッセージを意図した受信者のモバイルデバイスにルーティングします。メッセージはSMSまたはプッシュ通知の形式で送信することができます。

# 3. A2Pメッセージングの利点は何ですか？
A2Pメッセージングは、ビジネスが顧客と信頼性と効率性を持ってコミュニケーションを取る手段を提供します。個別化されたターゲティングメッセージを通じて、顧客エンゲージメントと満足度を向上させることができます。また、A2Pメッセージングは自動化することができ、ビジネスの時間とリソースを節約することができます。

# 4. A2Pメッセージングの使用事例は何ですか？
A2Pメッセージングは、アラートの送信、通知、リマインダー、マーケティングメッセージ、トランザクショナルメッセージなど、様々な目的で使用することができます。金融、ヘルスケア、小売、ホスピタリティなどの様々な業界のビジネスによって使用することができます。

# 5. ビジネスはどのようにしてA2Pメッセージングを実装できますか？
ビジネスは、メッセージングプロバイダを使用するか、自身のメッセージングインフラを構築することで、A2Pメッセージングを実装することができます。彼らはアプリケーションをメッセージングゲートウェイと統合し、アメリカのTelephone Consumer Protection Act（TCPA）などの規制に準拠することを確認する必要があります。
ClojureでHelloWorldプログラムを実装してみた

# 概要
ClojureでHelloWorldプログラムを実装してみました。以下のページを参考にしました。

https://qiita.com/ka_/items/a3f79b761e25d485f2a9

# インストール
以下のコマンドを実行しました。環境を構築しました。
```
$ sudo apt install clojure
```

# プログラム作成
以下のファイルを作成しました。ソースコードを作成しました。
```hello.clj
(println "Hello World!")
```

# プログラム実行
以下のコマンドを実行しました。
```
$ clojure hello.clj 
Hello World!
```

# まとめ
何かの役に立てばと。
[AWS Q&A 365][SNS]Daily Five Common Questions #70

# 1. What is A2P messaging? 
A2P messaging stands for Application-to-Person messaging which refers to the process of sending messages from an application to an individual's mobile device. 

# 2. How does A2P messaging work? 
A2P messaging usually involves using an API to connect to a messaging gateway, which then routes the message to the intended recipient's mobile device. The message can be in the form of SMS or push notification. 

# 3. What are the benefits of A2P messaging? 
A2P messaging provides a reliable and efficient way for businesses to communicate with their customers. It allows for personalized and targeted messaging, which can improve customer engagement and satisfaction. A2P messaging can also be automated, saving time and resources for businesses. 

# 4. What are the use cases for A2P messaging? 
A2P messaging can be used for a variety of purposes such as sending alerts, notifications, reminders, marketing messages, and transactional messages. It can be used by businesses in various industries including finance, healthcare, retail, and hospitality. 

# 5. How can businesses implement A2P messaging? 
Businesses can implement A2P messaging by using a messaging provider or building their own messaging infrastructure. They will need to integrate their application with the messaging gateway and ensure compliance with regulations such as the Telephone Consumer Protection Act (TCPA) in the United States.
Qiitaの記事の書き方

# 概要
Qiitaで記事を書くにあたって、MarkDown記法についてまとめてます。
※あくまで自分が使いそうなものだけをまとめています

参考：[Markdown記法 チートシート](https://qiita.com/Qiita/items/c686397e4a0f4f11683d")
# 目次
[文字のサイズ](#文字のサイズ)
[文字の装飾](#文字の装飾)
[リンクの挿入](#リンクの挿入)
[画像の挿入](#画像の挿入)
[コードの挿入](#コードの挿入)
[テーブルの挿入](#テーブルの挿入)
[リスト](#リスト)
[その他(改行、エスケープ等)](#その他)
## 文字のサイズ
文字のサイズは、先頭に♯を付けることで変更可能
h1～h6までの設定可能
#の後には␣(スペース)が必要
```html:記載例
# h1　
## h2
### h3
#### h4
##### h5
###### h6
```
# h1　
## h2
### h3
#### h4
##### h5
###### h6

## 文字の装飾
文字を**太字**にする
```html:記載例
文字を**太字**にする
```
文字を<font color="red">赤色</font>にする
```html:記載例
文字を<font color="red">赤色</font>にする
```
~~文字~~を打ち消す
```html:記載例
~~文字~~を打ち消す
```

## リンクの挿入
### 外部ページリンク
外部ページへのリンクは下記のように記載
```html:記載例
[Qiita](https://qiita.com/)
```
[Qiita](https://qiita.com/)

見出しにカーソルをあてて、左側のマークをクリックするとURLが見出しに紐づいたものに変更されるためこれを利用することも可能
<img width=50% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3459413/89713e08-75b5-fa4d-035c-3c407a9576b2.png">
[目次](https://qiita.com/yuki_2392/items/a543df4e0289c96e888f#%E7%9B%AE%E6%AC%A1)
```html:記載例
[目次](https://qiita.com/yuki_2392/items/a543df4e0289c96e888f#%E7%9B%AE%E6%AC%A1)
```
### 内部ページリンク
ページ内にリンクさせる場合は下記のように記載
()内の#は見出しの#の数にかかわらず1つのみ
```html:記載例
[目次に戻る](#目次)
```
   [目次に戻る](#目次)

<font color="red">注意事項</font>
&nbsp;&nbsp;()内は見出し名が大文字でも小文字で記載
 #### Sample
```html:記載例
[Sample](#sample)
```
[Sample](#sample)

## 画像の挿入
画像は下記のように記載することで表示可能
```html:記載例
## タイトルありの画像を埋め込む
![代替テキスト](画像のURL "画像タイトル")

## タイトル無しの画像を埋め込む
![代替テキスト](画像のURL)
```
適当な画像をCtrl+CでコピーしてCtrl＋Zで貼り付けるだけでも勝手にリンク生成してくれます。
例）サイト左上のロゴをwindowキー＋Shift＋Sでコピーして貼り付け
```html:記載例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3459413/a7a1d04e-4b8d-ba82-af92-13fe96156b4e.png)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3459413/6c67346f-60ac-d6a5-81fd-274730b0b8b7.png)
下記（HTML）のように記載することで、サイズも変更することができます。
```html:記載例
<img width="50" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3459413/6c67346f-60ac-d6a5-81fd-274730b0b8b7.png">
```
<img width="50" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3459413/6c67346f-60ac-d6a5-81fd-274730b0b8b7.png">

## コードの挿入
コードの挿入は「\`\`\`」でコードの前後を囲むように記載する
\`\`\` : 記載例
コード挿入
\`\`\`
``` : 記載例
コードの挿入
```
先頭の「```」の後に「言語 : ファイル名」などのように記載することでコード表示にタイトルを付けれる

\`\`\`java:test.java
System.out.println("Hello World!");
\`\`\`
```java:test.java
System.out.println("Hello World!");
```
## テーブルの挿入

```html:記載例
No |内容
---|---
1  |1の内容
2  |2の内容
```
No |内容
---|---
1  |1の内容
2  |2の内容

### 文字位置の調整
列単位で文字位置を指定できる
```html:記載例
左寄せ|中央寄せ |右寄せ
---  |:-:     |--:     ←この行で調整
text |text    |text
```
左寄せ|中央寄せ |右寄せ
---  |:-:     |--:
text |text    |text

## リスト
[数字付きリスト]
```html:記載例
1. 概要
1. 目次
1. 内容
```
1. 概要
1. 目次
1. 内容

### リスト途中で改行したい場合
リストの途中で改行しようとするとリストが崩れる
その場合は「␣␣␣␣\<br\>」で改行することによりリストNoを維持できる
（␣=半角スペース）
```html:リスト途中の改行
1. 概要
    <br>
1. 目次
    <br>
1. 内容
```
1. 概要
    <br>
1. 目次
    <br>
1. 内容

## その他
### 改行
```html:記載例
12<br>3
```
12<br>3
### エスケープ
文字の前に「 \ 」をつける
```html:記載例
12\<br\>3
```
12\<br\>3
2023年にRTM1.7.10サーバーを構築する

# はじめに

RTMサーバーをLinuxで立てよう！と思ったら以外につまずいたのでメモ。

# 構成要素

- Ubuntu 22.04 LTS x64
- Eclipse Temurin Java SE 8 JRE
- Minecraft Forge 1.7.10-10.13.4.1614
- MCRCON v0.7.2
- RTM 1.7.10.44
- NGTLib1.7.10.35

# Ubuntuのインストール
サーバー機にインストールし、実行用ユーザーを作成する。
※説明例では `minecraft` ユーザーを使用している。

# MCRCONのインストール

Systemdでデーモン化した際に操作ができるように、MCRCONをインストールする。

```shell
# 未導入であれば入れる
sudo apt install gcc make unzip
# お好みの作業用ディレクトリ内で
wget https://github.com/Tiiffi/mcrcon/archive/refs/tags/v0.7.2.zip
unzip v0.7.2.zip
cd mcrcon-0.7.2
make
sudo make install
```

# Temurin Java SE 8 JRE
直接wgetできないので[Temurin公式サイト](https://adoptium.net/temurin/releases/?version=8)から下記条件を指定して対象ファイルをダウンロードする。

- Operating System : Linux
- Architecture : x64
- Package Type : JRE
- Version : 8 - LTS

ダウンロード後、所定のディレクトリへ配置する。
配置後、ファイルを解凍して短くリネームする。
※説明例ではディレクトリに `/home/minecraft/jre/` を使用している。
※他バージョンのMinecraft Serverを動かす場合を想定して、パスは通さない。

```shell
tar -xvf OpenJDK8U-jdk_x64_linux_hotspot_8u372b07.tar.gz
mv jdk8u372-b07 8
```

# Minecraft Forgeのインストール

[Minecraft Forge](https://files.minecraftforge.net/net/minecraftforge/forge/index_1.7.10.html)はadfoc.usの仕様上、直接wgetできないのでブラウザからダウンロードして所定のディレクトリへ配置する。
※説明例では `/home/minecraft/mc/forge_1.7.0_rtm/` を使用している。

配置後、インストーラーを起動する。
インストール後にForgeのJARファイル名を短くリネームする。

```shell
/home/minecraft/jre/8/bin/java -jar forge-1.7.10-10.13.4.1614-1.7.10-installer.jar --installServer
mv forge-1.7.10-10.13.4.1614-1.7.10-universal.jar server.jar
```

Log4j脆弱性対策のXMLファイルをMinecraft公式サイトよりwgetする。
```shell
wget https://launcher.mojang.com/v1/objects/dd2b723346a8dcd48e7f4d245f6bf09e98db9696/log4j2_17-111.xml
```

Systemd用の起動・終了のシェルスクリプトを用意する。

```shell:start.sh
#!/bin/bash
cd ~/mc/forge_1.7.0_rtm
/home/minecraft/jdk/8/bin/java -Xmx16g -Xms8g -Dlog4j.configurationFile=log4j2_17-111.xml -jar ./server.jar nogui
```
※VMへのメモリ割り当ては、お使いの環境に合わせて調整してください。

```shell:stop.sh
#!/bin/bash
export MCRCON_HOST=localhost
export MCRCON_PORT=25575
export MCRCON_PASS=あなたのRCONパスワード
echo stop | /usr/local/bin/mcrcon -t
exit 0
```

一旦起動用スクリプトから起動し、EULAに同意できる場合は `eula.txt` を編集する。
MCRCONを利用するための設定を `server.properties` で行う。

```server.properties(追記/変更)
rcon.port=25575
enable-rcon=true
rcon.password=あなたのRCONパスワード
```

# Systemdへの登録

```/etc/systemd/system/rtm.service
[Unit]
Description=RTM Server Service

[Service]
Type=simple
User=minecraft
ExecStart=/home/minecraft/mc/forge_1.7.0_rtm/start.sh
ExecStop=/home/minecraft/mc/forge_1.7.0_rtm/stop.sh
TimeoutStopSec=3000
PrivateTmp=true
Restart=always

[Install]
WantedBy=multi-user.target
```

```shell
sudo systemctl enable rtm.service
sudo systemctl start rtm.service
journalctl -f -u rtm.service
```

起動を確認したら一旦Forge Serverを止めます。

```shell
systemctl stop rtm.service
```


# RTM等のディレクトリへの配置

[RTM本体](https://www.curseforge.com/minecraft/mc-mods/realtrainmod/files/4030455)と[NGTLib](https://www.curseforge.com/minecraft/mc-mods/ngtlib/files/4030452) は CurseForgeの仕様上やはりwgetできないので別途ブラウザからダウンロードする。

※今回の説明例の場合では `/home/minecraft/mc/forge_1.7.0_rtm/mods/` に配置する。

Forge Serverを起動し、ログを確認する。

```shell
sudo systemctl start rtm.service
journalctl -f -u rtm.service
```
jupyter notebookでopencvライブラリをインストールする方法

## 環境
windows11
jupyter notebook
python3

## 起こったこと
```
import cv2
```
でエラー（ライブラリが存在しない的な）。

ライブラリをインストールしようとして
```
!pip install opencv
```
と打ってShift+Enterで実行したが、以下のエラー
Could not find a version that satisfies the requirement opencv (from versions: none)

## 解決方法
```
!pip install opencv-python
```
でインストールできた。
【個人開発】大学生（？）が授業のコマで日程調整できるサイトを作ってみた

# はじめに
![Comma-sns.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1819316/a66fece7-e0d1-36ca-1af6-379d71be5e85.png)
[Comma - 時間割ベースの日程調整ツール](https://com-ma.app/)

こんにちは！
休学してコードを書きながらフラフラ生きている者です。
右往左往しながら、今年の４月末にサービスをリリースしたので、それの紹介をさせてもらいます。

# なにがきっかけ？
大学生は、基本的に __時間割をベースに__ 行動します。

月曜は２限までだから午後にバイトを入れよう、
火曜は３限が空きコマだから図書室に行こう、といった感じで。

なので、サークルの練習などの日程調整を時間割ベースでやると、楽だったりします。
僕の周りの人は、[tappy](http://tap-py.com/)というサービスを使ってこれを実現していました。
![スクリーンショット 2023-05-29 17.24.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1819316/bdeaaa1c-8b36-f674-f4fa-ad2f329e901e.png)

[tappy](http://tap-py.com/)は無料で使える素晴らしいサイトなのですが、
* __通信が暗号化されていない（https化されていない）__
* __日程調整を作成するときに手入力が多い__
* __編集ページが操作しづらい__

といったところが個人的に気になりました。

そこで、新しく日程調整サービスを作ろうと思いました。

# 機能
### 少ないタップ数で楽に日程調整を作成
日程調整の期間はカレンダーから、時限数はドロップダウンから選択して楽に作成できます。
![test10.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1819316/4326c536-c9dc-d491-9651-25167bfe5473.gif)



### 週間スケジュールの設定で効率的に
１週間の時間割を登録しておけば、より効率的に日程調整をすることができます。
![timetable.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1819316/32165e96-2506-a478-b74b-d52f1c2bf30d.gif)

### 同じような時期に複数のイベントがあるときはペーストで
ペースト機能を使えば、複数の日程調整も楽に済ませられます。

下の例では、「test」イベントと「test2」イベントの日程調整期間のうち、5/16〜5/21が被っているので、その期間の内容がペーストされます。
![paste.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1819316/3f0a1b15-b2c9-67d8-b16d-cbf504b94019.gif)

# 技術スタック
### バックエンド→Laravel
会員登録機能や、メール送信機能、ミドルウェアなどWebアプリに必須な機能が揃っていてとても良い選択だったと思います。
### フロントエンド→Vue.js + Vuetify
Vue.jsの双方向性バインディングは諸刃の剣ですが、個人開発ではスピーディーな開発を可能にしてくれるので、I love Vue.jsです。UIフレームワークはVuetifyにしました。短いコードでいい感じに仕上がるのでお気に入りです。

### データベース→契約中のレンタルサーバーのやつ
レンタルサーバー借りてるので、これが一番手っ取り早かったです。

# 収益は?
ゼロです。というかマイナスです。
サーバー代とドメイン代合わせて __-900円/月__ って感じです。
クリック広告を出すという選択肢もありましたが、ユーザーのストレスになるのでやめました。
収益化するならサブスクリプション型かなと思っていますが、ターゲット層が大学生ですし、課金したいと思えるほどのサービスではないと思うので、なかなか難しいですねー。
収益としてはマイナスですが、いい開発経験になったと思っています。

# 今後の課題
このサービスの一番の課題は、__ログインが必須__ だという点です。
ログインは面倒くさいものなので、利用するまでのハードルが高くなってしまいます。

しかし、最近これを解消するアイデアが浮かびました！
それは __モバイルアプリのリリース__！

モバイルアプリでは、__生体認証__ などが使えるのでログインのハードルがかなり下がるのでは、と考えました。

というわけで、絶賛モバイルアプリ開発中！
![mobile.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1819316/52f46cff-e9e6-0603-e811-1fd99b47e797.gif)

これからもガンガン開発やっていきたいと思います。
最後まで読んでいただきありがとうございました！
プログラミング学習のロードマップ


# １　作りたいものを決める

よく、やっとけば潰しが効くから「Java」を学ぶ！今流行りだから「Python」を学ぶ！
という意見を見かけますが、これは手段と目的が逆転している状態です。
あくまでプログラミング言語というものは、生活を便利にするサービスを作るための「手段」ということを忘れてはいけません。
ここが明確に定まっていないと挫折してしまう確率が高くなってしまいます。

# 2 学習する言語を決める。

作りたいものが決まったら、それを作るために学習する言語を決めましょう。
例えば、ECサイトを作りたいからフロントを作るために、HTML/CSS,JavaScript
バックを作るためにPHP、Laravel、SQLを学ぶといった具合になります。

↓どの言語で何ができるのか網羅的に記載されているので一読をお勧めします

https://www.amazon.co.jp/%E7%9F%A5%E8%AD%98%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E3%81%AE%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E5%AD%A6%E7%BF%92%E8%A1%93-%E7%8B%AC%E5%AD%A6%E3%81%A7%E8%BA%AB%E3%81%AB%E3%81%A4%E3%81%91%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE9%E3%81%A4%E3%81%AE%E5%AD%A6%E7%BF%92%E3%82%B9%E3%83%86%E3%83%83%E3%83%97-%E5%8C%97%E6%9D%91-%E6%8B%93%E4%B9%9F/dp/4798060127


# ３ 基礎を学ぶ

上記で決めた言語の基礎を学んでいきましょう。
ここで大切なのは、「完全に理解できなくても次に進む」ということです。
よく、基礎は大切だから時間をかけてみっちり学ぼうとされる方がいますが、これは陥りがちな間違いです。
プログラミングは学校のテストと違って、「カンニングOK」なので、「暗記」する必要はありません。
とにかくここは完璧に理解できなくてもいいので **ざっくり全体像を理解する**ことを前提に進めていきましょう。
基礎学習おすすめのサービス
↓
プロゲート

https://prog-8.com/courses

ドットインストール

https://dotinstall.com/

# 4 既存のサービスのコードを写してながら形になるものを作ってみる

基礎は一通り学習しても、0から自分でサービスを作るというのはまだ難しいと思います。
そこで、既存のサービスを見様見真似で作ってみることをお勧めします。いわゆる写経と呼ばれるものです。
実際のサービスとなるものを作りながら、プログラミングの全体像を把握して、上記で学んだ基礎が、どのような形で動くのかといったことを手を動かしながら学ぶことができます。
このことで基礎の定着にも繋がりますし、実務を擬似的に体験することができます。


# 5 ０から自分でサービスを作る

写経で基礎の定着と全体像を把握したら、次は自分でオリジナルのサービスを作って見ましょう。
ここで大切になってくるのが不完全でもいいのでとにかく完成させてできればリリース、公開するということです。
基礎学習と同じで、「まず終わらせる」ことが大切です。
Facebook創業者のマークザッカーバーグも
完璧を目指すよりまず終わらせろ（英語：Done is better than perfect）
と述べております。
最初から完璧を目指して開発するのではなく、設計・開発・テスト・改善のサイクルを短期間で繰り返し、少しずつ質を高めていくことを目標に開発を進めていきましょう。
Mulesoft Dataweaveを使ってみた

# はじめに
みんなさん　こんにちは。

Mulesoft Dataweaveは、データ統合プラットフォームであるMuleSoftの中核的な機能の一つであり、異なる形式のデータを変換するために使用されます。

この記事では、Dataweaveの概念と利点を紹介していきます。

# Dataweaveとは
Dataweaveは、Javaで書かれた柔軟で強力なスクリプト言語であり、JSON、XML、CSV、フラットファイル、およびデータベースなど、さまざまな形式のデータを変換することができます。Dataweaveは、データ変換のための完全なエコシステムを提供し、多くのビジネスプロセスを簡素化し、効率化することができます。

# Dataweaveの機能
Dataweaveには、多くの便利な機能が備わっています。一つは、データのフィルタリングと変換です。

Dataweaveは、構造化されたデータをフィルタリングし、必要な部分だけを抽出することができます。

また、データの変換も簡単に行うことができます。例えば、JSON形式からXML形式に変換することができます。

Dataweaveは、Javaのコレクションと同様に、データのマッピングを簡単に行うことができます。

また、Dataweaveは、複数のデータソースからデータを結合することもできます。

# Dataweaveの利点
Dataweaveは、Mulesoftの中で非常に重要な機能であるだけでなく、多くの利点を提供しています。

最も重要な利点の一つは、非常に柔軟であることです。Dataweaveは、多くの異なるデータ形式を変換することができ、Javaのようなスクリプト言語を使用するため、柔軟性が高く、多くのビジネスプロセスを効率化できます。

また、Dataweaveは、ビジネスプロセスの実行時間を短縮することができ、ビジネスプロセスの品質を向上させることができます。Dataweaveは、Mulesoftの中でも非常に重要な機能であり、多くのビジネスプロセスを簡素化し、効率化することができます。

# 終わりに
Mulesoft Dataweaveは、異なる形式のデータを変換するために使用される強力なツールです。Dataweaveは、柔軟で強力なスクリプト言語を使用するため、多くのビジネスプロセスを効率化することができます。

最後までお読みいただき、本当にありがとうございました。
Mulesoftに関する、すこし理解できましたら幸いです。気になる点があったらお知らせください。
Nuxt3をspaにしてレンタルサーバーで使う

さくらのレンタルサーバーに静的サイトとしてデプロイしたかった。


まずconfigを変更.
今回はルートパスが変わるので公開時のルートパスに変更しておく
```nuxt.config.ts
export default defineNuxtConfig({
  ssr: false,
  app: {
    baseURL: '/directory-name/'
  },
...
```

次に静的ファイルを出力する。
```terminal:terminal
npx nuxi generate  
```


　　　
　　　
するとdistフォルダ内に静的ファイル群ができるので、
それをレンタルサーバーにアップ。

最後に.htaccessを追加してルートパスを合わせる。

```.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /directory-name
RewriteRule ^directory-name/index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /directory-name/index.html [L]
</IfModule>
```
Visualforce でMap型データの使い方

コントローラで定義したMap型のデータを出力したい時はapex:repeatを使います。
```ruby:apex
public with sharing class samplePageController {
    public Map<String,String> directors {
        get {
            return new Map<String, String> {
                'Kieslowski' => 'Poland', 
                'del Toro' => 'Mexico', 
                'Gondry' => 'France'
            };
        }
        set;
    }
}
```

```ruby:visualforce
<apex:page controller='samplePageController'>
    <apex:repeat value="{!directors}" var="dirKey">
        Key:<apex:outputText value="{!dirKey}"/> 
        Value:<apex:outputText value="{!directors[dirKey]}"/><br/>
    </apex:repeat>
</apex:page>
```

出力結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330192/b5024082-497a-d1ff-3647-064eb70807f8.png)

参照資料：
https://developer.salesforce.com/docs/atlas.ja-jp.pages.meta/pages/pages_dynamic_vf_maps_lists.htm
Scalaスケーラブルプログラミング第4版 第06章 関数型スタイルのオブジェクト 読書メモ

![関数型スタイルのオブジェクト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27987/9e38967d-6841-08c3-aeaf-2af1e0916086.png)

基本的にはJavaと同じ、というよりJavaより簡潔になっているイメージですね。
あんまり`require`を使った事前条件はみたことがない。。。
Javaでいうところの`assert`みたいなものなのだろうか。表明の手段としてはよいと思うので使っていきたいですね。
MacでPATHを通す

# はじめに

こんにちは、yoyamです。
元々IT企業の営業をしていたのですが、2023年1月から技術職にうつりました。
自らの備忘録として超初心者向けの記事を残します。

# 何を書いたか

手元のMacにソフトウェア（本記事ではJDK）をインストールした後にPATHを通した方法を記録。

①対象ソフトウェアがインストールされているか確認
②ソフトウェアの在処を確認する（＝通したいPATHの確認）
③環境変数の設定
④zshに環境変数を残す

# 本題
①対象ソフトウェアがインストールされているか確認

バージョン確認
自身がインストールしたバージョンが表示されればOK。

```
% java -version
java version "1.8.0_311"
Java(TM) SE Runtime Environment (build 1.8.0_311-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.311-b11, mixed mode)
```

<br />
<br />
②ソフトウェアの在処を確認する（＝通したいPATHの確認）
<br />
<br />
Library配下の任意のファイルを表示（本記事ではJava）


```
% ls /Libraly/Java
Extensions		JavaVirtualMachines
```
さらに任意のソフトウェアが格納されていそうなファイルを順に辿っていく。
Tab（→|）を押すと候補が出てくる。
```
% ls /Libraly/VirtualMachines
jdk1.8.0_311.jdk
% ls /Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/Contents/
CodeResources	Home		Info.plist	MacOS		_CodeSignature
```
/Homeを見つけることができた。
<br />
③環境変数の設定

上記②のように在処まで毎回辿ってソフトウェアを起動するのは非常に面倒。
環境変数JAVA_HOMEにJavaの在処を代入し、
```
% export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/Contents/Home
```
PATHを通す($PATH:以下に任意の環境変数を入力)
```
% export PATH="$PATH:$JAVA_HOME/"
```
echoコマンドでPATHが通ったか確認。一覧の最後に追加されていた。
```
% echo $PATH
（省略）:/Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/Contents/Home/
```
<br />
<br />
④zshに環境変数を残す
<br />
<br />
設定した環境変数は今回使ったターミナルウィンドウを閉じると消える（らしい）。

viエディタでzshに残し、半永久的に使えるようにする。
```
% vi ~/.zshrc
```
上記をコマンド入力すると、以下のような画面が出てくるので
```
# Load Angular CLI autocompletion.
source <(ng completion script)
~
~
~
"~/.zshrc" 9L, 321B
```
iを押し、INSERT状態にする。
設定した環境変数を入力し、escボタンを押す。
```
# Load Angular CLI autocompletion.
source <(ng completion script)

export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/Contents/Home
export PATH="$PATH:$JAVA_HOME/"
~
~
~
-- INSERT --
```
:wqと入力し、Enterボタンを押す。
```
# Load Angular CLI autocompletion.
source <(ng completion script)

export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/Contents/Home
export PATH="$PATH:$JAVA_HOME/"
~
~
~
:wq
```
catコマンドでzshに環境変数が残ったか確認した。
```
% cat ~/.zshrc
# Load Angular CLI autocompletion.
source <(ng completion script)

export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/Contents/Home
export PATH="$PATH:$JAVA_HOME/bin/"
```


# 参考文献

[Qiitaで簡単に記事を書くためのフォーマット](https://qiita.com/kenseitogari1/items/1dcf4328d54e9f2c087c)

# 最後に


最後まで読んでいただきありがとうございます。
静力学と材料力学 基本例題1.06 P3「材料力学演習(20221021)」をsympyでやってみた。 

２通りで
# オリジナル
基本例題1.06 P3
http://zairikiweb.starfree.jp/zai_enshuh/zai_enshuh_ver.3.3.pdf#page=9

「材料力学演習(20221021)一括(ver.3.3)」を勉強したい。＞sympy
https://qiita.com/mrrclb48z/items/c3274daf5f7a99cfe027#%E4%BD%9C%E6%A5%AD%E4%B8%AD%E7%A7%81%E3%81%AE%E8%A7%A3%E7%AD%94sympy

# sympyで(pdfの手順で実行)
```python
from sympy import *
PA, PB, PC=symbols('PA  PB  PC',real=True)
NAB,NBC   =symbols('NAB NBC   ',real=True)
#
myAF=Eq(-PA +NAB   ,0)
myBF=Eq(-NAB-PB+NBC,0)
myCF=Eq(-NBC+PC    ,0)
myABCF=Eq( myAF.lhs+myBF.lhs+myCF.lhs,myAF.rhs+myBF.rhs+myCF.rhs)
print("#",myABCF)
PA_ans=solve(myABCF,PA)[0]
print("#",PA_ans)
NAB_ans=solve(myAF,NAB)[0].subs({PA:PA_ans})
NBC_ans=solve(myCF,NBC)[0].subs({PA:PA_ans})
print("#",NAB_ans,NBC_ans)
mySubs={PB:7,PC:10}
print("#",NAB_ans.subs(mySubs),NBC_ans.subs(mySubs))
# Eq(-PA - PB + PC, 0)
# -PB + PC
# -PB + PC PC
# 3 10
```
# sympyで(solveを1回で実行)
```python
from sympy import *
PA, PB, PC=symbols('PA  PB  PC',real=True)
NAB,NBC   =symbols('NAB NBC   ',real=True)
myAF=Eq(-PA+NAB    ,0)
myBF=Eq(-NAB-PB+NBC,0)
myCF=Eq(-NBC+PC    ,0)
ans=solve([myAF,myBF,myCF],[PA,NAB,NBC])
print("#",ans)
mySubs={PB:7,PC:10}
print("#",ans[NAB].subs(mySubs))
print("#",ans[NBC].subs(mySubs))
# {PA: -PB + PC, NAB: -PB + PC, NBC: PC}
# 3
# 10
```
①私の環境は,pycharmです。
②よく聞くのは、Jupyterです。
③web上で、上記のソースを「SymPy Live shell」に、コピー貼り付けでもできました。
黒背景の右上に、マウスを移動すると、コピーマークが発生します。
???　タブレット環境で、コピー貼り付けが実行できませんでした。???

https://live.sympy.org/

# Mathematicaで
勉強中

# 作図
勉強中
UE5 C++初期化備忘録

C++で実装する場合、どこで初期化するか悩んだので備忘録
Superクラスを呼ぶのを忘れずに

## Actorの初期化(レベルが開始したときに呼ばれる)
```
virtual void BeginPlay() override;

void MyActor::BeginPlay()
{
    Super::BeginPlay();
    // 任意の初期化

}
```

## Widgetの初期化(表示するときに呼ばれる)
```
virtual void NativeConstruct() override;

void MyWidget::NativeConstruct()
{
    Super::NativeConstruct();
    // 任意の初期化

}
```
[Java]Listを任意の単位で分割したいときに便利なライブラリのメソッド

『Listを任意の単位で分割して、分割したリストごとに処理をしたい』なんてケースはありませんか？

たとえば、社員検索APIにリクエストが発生する場合に、パフォーマンスを考慮して、一回のリクエストに指定できる社員IDリストは上限100までと決まっているとか。

そういった場合に、リストを決められた上限数ごとに分割してくれる関数があると便利です。

そこで、`ListUtils.partition()`という関数を利用します！


# ライブラリの依存追加
本記事ではビルドツールにGradleを利用します。
`build.gradle`の`dependencies`に、下記の依存関係を追加します。
```gradle:build.gradle
dependencies {
	implementation 'org.apache.commons:commons-collections4:任意のバージョン'
}
```

# サンプルコード

たとえば、ある複数人のメンバーをランダムに２人組のグループにして、グルーピングした結果をコンソールに出力するという簡単なプログラムがあるとします。

| メソッド | 役割 |
|:-:|:-:|
| main()  | membersを生成してgroupingMember()を呼び出す  |
| groupingMember()  | membersをランダムな2人組のグループに分割し、<br>グループ単位にannounceGroup()を呼び出す  |
| announceGroup()  | 引数のgroupをコンソールに出力する  |

```java:Main.java
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.commons.collections4.ListUtils;

public class Main {

  private static int count = 1;

  public static void main(String[] args) {
    List<String> members = Arrays.asList("佐藤", "鈴木", "高橋", "伊藤", "上野", "三浦");
    groupingMember(members);
  }

  /*
    メンバーを受け取りランダムにグループ分けをする.
 */
  public static void groupingMember(List<String> members) {
    // ランダムで2人組のグループを作成する.
    Collections.shuffle(members);
    ListUtils.partition(members, 2).forEach(Main::announceGroup);
  }

  /*
    グループメンバを発表する.
   */
  private static void announceGroup(List<String> group) {
    System.out.println("第" + count + "グループ: " + group);
    count++;
  }

}
```
## ポイント
- `Collections.shuffle(members);`で`members`の要素をランダムに並び替えをしています。
- `ListUtils.partition(members, 2)`によってリストである`members`を2要素単位で分割しています。
- `forEach(Main::announceGroup)`はラムダのメソッド参照の記述で、`forEach(list -> announceGroup(list))`と同じ意味です。


# 実行結果
main(）を実行してみます。
```java
> Task :Main.main()
第1グループ: [三浦, 佐藤]
第2グループ: [上野, 鈴木]
第3グループ: [高橋, 伊藤]
```
きちんと２人単位にグルーピングされて、グループごとにコンソールに出力されていることが分かりますね。

# まとめ
こんな感じで、`ListUtils.partition(リスト, 分割したい単位)`と記述すれば、簡単にListを分割してくれます。

とても便利ですね！

以上になります 🙌
Qiita記事を詳細に検索する2つの方法

## 概要
私が使うQiita記事を詳細に検索する2つの方法を紹介させて頂きます。

## オプションで検索
### 基本的な使い方
私がQiita記事を詳細に検索する1つ目の方法として、`オプションで絞り込んで検索する方法`が御座います。

例えば自分の記事だけで絞り込みたい場合、Qiita検索フォームに`user:ユーザー名`と入力し検索します。
例として[私の場合](https://qiita.com/search?q=user%3Akimascript)は、このようになります。
### グルーピング
タグとユーザーは以下のように`,`で区切り、複数のキーワードをグルーピングして検索する事も可能です。
- ユーザー
`例: user:user1,user2`
- タグ
`例: tag:Rails,JavaScript`

### 複合オプションを活用
当然、オプションを掛け合わせて検索することもできます。
その場合は以下の様に記述いたします。

`例: user:user1  tag:Rails,JavaScript`

### タグの種類
タグの種類は、Qiitaヘルプに掲載されている[「検索時に利用できるオプション」](https://help.qiita.com/ja/articles/qiita-search-options)から引用し掲載致します。

|オプション|説明|
|:-|:-|
|title:Git|タイトルに「Git」を含んでいる|
|body:Ruby|本文に「Ruby」を含んでいる|
|Ruby OR Rails|本文に「Ruby」または「Rails」を含んでいる|
|code:function|コードに「function」を含んでいる|
|tag:Rails|タグに「Rails」を含んでいる|
|tag:Ruby,Rails|タグに「Ruby」または「Rails」を含んでいる|
|-tag:Ruby|「tag:Ruby」を含まない|
|user:qiita|記事が「qiita」によって作成された|
|org:qiita-inc|記事が「qiita-inc」のOrganizationに紐付いている|
|stocks:>3|記事が「3件」より多くストックされている|
|created:>2023-02-22|記事が「2023-02-22 以降」に作成された|
|updated:>2023-02|記事が 「2023-02-01 以降」に更新された|

## Qiigle
Qiita記事を詳細に検索する2つ目の方法として行っているのが、[Qiigle](https://qiigle.com/)というサービスを使用する方法です。
詳しくは以下の記事を参照頂きたいのですが、細かい絞り込みや自分の記事にも簡単にアクセスする事ができます。
[【Qiigle】というQiitaの記事を検索するサービスを作りました](https://qiita.com/d0ne1s/items/ea9d0154d56c7cfd2128)
【ChatGPT無＋Windowsバッチ】目標達成まで、時間が掛かる（悲）　最後に注意点あり。


　どうも、カーブミラーです。

　ここのところ、ChatGPTに指示して、
　Windowsバッチを作ろうとやっています。
　ここにはコードは書きませんけどねw
　ただでさえ、長いので。

　簡単なコマンドならば、ChatGPTからは、すぐに出てきます。
　特定のファイルを特定のディレクトリに移動とかコピーする程度ならば、大丈夫です。指示次第かもしれませんけどね。


　でも、ちょっと複雑な指示をバッチ化しても、それらしいコードを教えてくれます。

　問題は、ここからです。
　あっ、ChatGPT（無料版）での話なので、
　　もしかしたら、GPT4.0ならば、
　　　問題にならない？かも？

　教えてくれたバッチを実行してみると、動かないとか、間違った結果を返してくる。

　もちろん、自分にノウハウがあれば、
　　それを修整できるのでしょうが。
　mkdirとかcopyなら、わかるんだけど……無理！

　ChatGPTが二転三転というか、グルグルするというか。指摘すると「すみません」と謝罪からはじまって、同じことをはじめる。

　**こんなとき、私は、そのChatは諦めます。
　そんなグルグルに掛ける時間は、単なるムダですからね。
　だから、私はNewChatで、新しくはじめます。**

　これを悟るのに、かなり掛かりましたけどねw
　マジで、ひとつのバッチに何日も掛けました（悲）


　バッチ作成をしたい人に
　　向けての忠告をしておきます。
　　　経験から得たことですので、
　　　　足らないかもしれませんが。

・Windowsのバージョンによって、
　　コマンドプロンプトもバージョンが
　　　違います。
　　バッチを頼む以上、このことは、
　　　指示する上で、第一に考えてください。
　　コマンドプロンプトで確認するには
　　　「**ver**」でできます。

・日付を使う場合、
　　日本では、年月日（yyyy/mm/dd）ですが、
　　米国では、月日年（mm/dd/yyyy）です。
　　そして、Windowsは米国産。
　　つまり、システムは後者。
　　yyyy/mm/ddから年月日に分割するロジックをChatGPTに頼むと、
　　mm/dd/yyyyで分割しようとします。
　　これでかなりの時間を消費しました。
　　ご注意を。

・たまに、ChatGPTが出すコマンドが、
　　意味不明なものがあります。
　　　自分が知らないだけかもですが。
　　できれば、コマンドプロンプトを
　　　別に出しておくと良いです。
　　「**コマンド /?**」で機能やオプションが出てきます。
　　あっ、“コマンド”は、ChatGPTが出したコマンドです。

・最後にこれは結構、大事なことなのですが
　　バッチファイルを保存する際は、
　　拡張子をbatに、SJISで保存しましょう。
　　これを守らないと、実行しても失敗します。マジで。


最後に、感想。
　バッチって、構造化プログラミングが
　　可能なんですね。
　　　for文だったり、サブルーチンが
　　　　使えるとは、思いませんでした。
　　　　　ふつうのこと？
　でも、バッチでプログラミングは大変です。
　　ChatGPTとのやり取りも
　　　時間が掛かります。
　　　　ほかのプログラミング言語が
　　　　　使えるならば、そちらをお勧めします。

　では。
***
今回、作ったBackupバッチを
　アップしました。
[【ChatGPT＋Windowsバッチ】作ったBackupバッチ完成（手直しあり）](https://qiita.com/kabumira/items/88587204d56a0700a284 "")
【GitHub】コードの高度検索をやっていこう

## はじめに

先日、[GitHub、コード検索とコードビューの一般提供(GA)を開始](https://github.blog/jp/2023-05-16-github-code-search-is-generally-available/) しました。これにより、誰でも GitHub 上のコードを高度検索することができるようになりました 🎉 。その使い方について分かりやすいサイトがあまり見当たらなかったので、自分のメモがてらまとめようと思った次第です。

## 検索方法一覧

例を見たら大体わかると思います 👍
※大文字・小文字は考慮できてなさそうでした。（ご存じの方がいればコメント頂けると嬉しいです！）

### 部分一致で検索する

ダブルクォーテーションを利用します。
例 : ["LOOP test failed"](https://github.com/search?q=%22LOOP+test+failed%22&type=code)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/1e982d07-a427-681f-3390-605087f827ea.png)

### 正規表現を使って検索する

スラッシュを利用します。
例 : [/LOOP.+failed.+;$/](https://github.com/search?q=%2FLOOP.%2Bfailed.%2B%3B%24%2F&type=code)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/22706bc5-32db-4689-5176-c1505d18bfc7.png)

### ファイルを検索する

`path:` を利用します。
例 : [path:README.md](https://github.com/search?q=path%3AREADME.md&type=code)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/4f1f3acc-0cac-c4ec-0376-086f7b3e4ef6.png)

### プログラミング言語を指定して検索する

`language:` ( または `lang:` )を利用します。
例 : [language:C LOOP test failed](https://github.com/search?q=language%3AC+LOOP+test+failed&type=code&l=C)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/c4f8c42d-d03e-0097-441f-13bafc1aaa64.png)

### ディレクトリを指定して検索する

`path:` を利用します。
例 : [path:\*\*/driver/\*\* "LOOP test failed"](https://github.com/search?q=path%3Adrivers%2F**+%22LOOP+test+failed%22&type=code&l=C)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/b9b89a67-40b5-22f4-ce61-757c4dba68fb.png)

### AND, OR, NOT 検索

括弧と `AND, OR, NOT` を利用します。（括弧は無くても動きます。）
例 : [(lang:c OR lang:Java ) "LOOP test failed"](https://github.com/search?q=%28lang%3Ac+OR+lang%3AJava+%29+%22LOOP+test+failed%22&type=code&l=C)
![スクリーンショット 2023-05-29 19.02.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/857a3e4d-8a5e-656d-d1ba-95cb16209b45.png)

### 条件を複数指定して検索する

カンマを利用する方法を見かけましたが、前半の条件しか反映されないようでした。ので、`OR` を使うようにしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/eb897166-e8ca-9984-407d-139f574da9ea.png)

### 色々組み合わせて検索してみた

例 : [org:github repo:github/linux (lang:Markdown OR lang:C) ("#include \<linux/kernel.h\>" AND /".+failed.+"/)](https://github.com/search?q=org%3Agithub+repo%3Agithub%2Flinux+%28lang%3AMarkdown+OR+lang%3AC%29+%28%22%23include+%3Clinux%2Fkernel.h%3E%22+AND+%2F%22.%2Bfailed.%2B%22%2F%29&type=code)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343913/2048e361-689f-8644-171a-5153195c0045.png)

## おわりに

運用しているシステムにエラー発生した際に、エラーメッセージからシュッと周辺コードまで飛んで、パッと原因を想像して提示できると先輩風吹かせられるので、ぜひ覚えましょう（笑）
Jenkins+Apacheで「リバースプロキシーの設定がおかしいようです。」が消えないときの設定

以下の設定は、Apache設定の **トップレベル** もしくは **VirtualHost直下** に書きましょう。

    AllowEncodedSlashes NoDecode

中途半端なところに書くと有効にならない場合があります。

参考: https://httpd.apache.org/docs/2.4/en/mod/core.html#allowencodedslashes

> Context: **server config**, **virtual host**
Pythonで辞書型(id含む)のリストの差分を求める

## はじめに
辞書型のリストのパラメータ同士を比較し、差分を求める必要があったので記しておく。
パラメータの形式は、下記のようなIDを持った辞書型のリスト。
```python:
dl = [
    {'id': 'test001', 'value': '111'},
    {'id': 'test002', 'value': '222'},
    {'id': 'test003', 'value': '333'}
]
```

## コード 
```python:test.py
dl1 = [
    {'id': 'test001', 'value': '111'},
    {'id': 'test002', 'value': '222'},
    {'id': 'test003', 'value': '333'}
]

dl2 = [
    {'id': 'test002', 'value': '222'}
]

s1 = set(x['id'] for x in dl1)
s2 = set(x['id'] for x in dl2)

diff = [{'id': x} for x in s1 - s2]

result = [d for x in diff for d in dl1 if x['id'] == d['id']]

```

## 結果
```python:
[{'id': 'test001', 'value': '111'}, {'id': 'test003', 'value': '333'}]
```

## 解説
- 辞書型のリストからIDのみを抜き出し、set型に変換
```python:
s1 = set(x['id'] for x in dl1)
s2 = set(x['id'] for x in dl2)
```
set型に変換してから比較することで差分を得られるが、
内容が辞書型である場合、hashableでないためにエラーになる。
その為、辞書の中でユニークな値であるIDを抜き出しset型に変換。

- IDの差分を得る
```python:
diff = [{'id': x} for x in s1 - s2]
```
IDの差分を取得。

- IDで合致する要素を抜き出し、辞書型のリスト同士の差分の結果とする
```python:
result = [d for x in diff for d in dl1 if x['id'] == d['id']]
```
取得したIDのリストと辞書型のリストをループさせ、
ID同士で比較して合致したものを抜き出す。

下記はワンライナーじゃないバージョン
```python:
result = []

for x in diff:
    for d in dl1:
        if x['id'] == d['id']:
            result.append(d)
```

## おわりに
一撃で差分を取るスマートな方法ないですかね。