OmniAICreator/Qiita-1.07M huggingface dataset:
【WIP】ActiveRecord::Enum

## Enum is 何
- enumは``列挙型``

## 定義例
``` ruby
class Book < ApplicationRecord
  enum sales_status: {
    reservation: 0, # 予約受付中
    now_on_sale: 1, # 発売中
    end_of_print: 2, # 販売終了
  }
end
```

#### 保存のされ方
- シンボル、文字列、数値を渡しても戻り値が"now_on_sale"と表現される
``` ruby
irb(main):001:0> Book.create(sales_status: :now_on_sale)
=> #<Book id: 1, sale_status: "now_on_sale">

irb(main):002:0> Book.create(sales_status: "now_on_sale")
=> #<Book id: 2, sale_status: "now_on_sale">

irb(main):003:0> Book.create(sales_status: 1)
=> #<Book id: 3, sale_status: "now_on_sale">
```

#### 状態の確認
- メソッドで状態を確認できる
``` ruby
irb(main):001:0> book = Book.last

irb(main):002:0> book.now_on_sale?
=> true

irb(main):003:0> book.end_of_print?
=> false
```

- enumの値の末尾に「!」付きのメソッドを使うと、そのenumの値へ更新できる。（DB上にも反映）
``` ruby
irb(main):004:0> book.end_of_print!

irb(main):005:0> book.end_of_print?
=> true

irb(main):006:0> book.now_on_sale?
=> false
```

- 直接参照すると文字列の値が取得可能
``` ruby
irb(main):007:0> book.sale_status # 定義された値
=> "end_of_print"

irb(main):008:0> book.sales_status_before_type_cast # DBに保存されている実際の値
=> 
```

- 定義の確認
``` ruby
irb(main):009:0> Book.sale_statuses
=> {"resercation"=>0, "now_on_sale"=>1, "end_of_print"=>2}
```

- 未定義の値を保存しようとすると``ArgumentError``が発生
``` ruby
irb(main):010:0> Book.create(sale_status: hogehoge) 
ArgumentError('hogehoge' is not a valid sales_status)
```

- scopeとしても利用可
``` ruby
irb(main):011:0> Book.now_on_sale
 Book Load (0.4ms) SELECT "books".* FROM "books"
 WHERE "books". "sales_status" = ?
 LIMIT ? [["sales_status", 1], ["LIMIT", 11]]

irb(main):012:0> Book.not_now_on_sale
 Book Load (0.4ms) SELECT "books".* FROM "books"
 WHERE "books". "sales_status" != ?
 LIMIT ? [["sales_status", 1], ["LIMIT", 11]]
```
blastengineのPython SDKを使って大量の宛先を指定する

blastengineはエンジニアフレンドリーなメール配信サービスです。APIとSMTPリレーの両方をサポートしており、手軽に素早くメール配信ができるようになっています。

今回はPythonでblastengineのAPIを簡単に使えるSDKを開発しましたので、使い方を紹介します。現在はトランザクションメール（即時発信メール）とバルクメール（一括配信）をサポートしています。今回は一括配信する際に大量の宛先を指定する方法を解説します。

## インストール

インストールはpipコマンドで行ってください。

```
pip3 install blastengine
```

## インポート

クライアントとバルクをインポートします。

```py
from blastengine.Client import Blastengine
from blastengine.Bulk import Bulk
```

## 初期化

Blastengineを初期化します。ユーザ名とAPIキーを使います。

```py
# 初期化
Blastengine('USER_NAME', 'API_KEY')
```

## メールオブジェクトの用意

バルクメールは `Bulk` を使います。件名やテキスト本文などを指定します。 `__name__` となっているのは、配信先ごとに置き換えられる文字列になります。

```py
# バルク（一括発送）メールオブジェクトの作成
bulk = Bulk()
# 情報を適用する
bulk.subject('メールの件名')
# __name__ は置き換えられる文字列
bulk.text_part('テキスト本文 __name__')
# 2つ目の引数（名前）はなくても大丈夫です
bulk.fromAddress('info@example.jp', '管理者')
```

### 添付ファイルの追加

添付ファイルは `attachments` メソッドで、ファイルのパスを指定してください。

```py
# 添付ファイルがある場合
bulk.attachments('./test.py')
bulk.attachments('./image.png')
```

### 一度保存する

このメールテンプレートができた段階で一度保存します。

```py
try:
	bulk.begin()
except Exception as e:
	# APIエラー
	print(e)
```

## 少数の宛先を設定する

次に宛先を設定します。この時、置き換え文字列を設定できます。この方法では50件まで指定できます。51件目を指定すると、Exceptionエラーが発生します。

```py
bulk.to('user1@example.com', [{
	'__name__': 'User1'
}])
bulk.to('user2@example.com', [{
	'__name__': 'User2'
}])
```

宛先を設定したら、保存を行います。保存すると宛先のリストはリセットされます。

```py
bulk.update()
```

## 大量の宛先を設定する

大量の宛先を指定する場合にはCSVアップロードを使います。[テンプレートはこちらからダウンロード](https://blastengine.jp/documents/example.csv)できます。

```csv
email,__prop1__,__prop2__,__prop3__
test@example.jp,テスト,テスト太郎,20200101
sample1@example.com,サンプル,サンプル次郎,20210101
```

このファイルをBulkクラスのcsv_importで指定します。そうするとJobオブジェクトが返ってきます。

```py
job = bulk.csv_import('./example.csv')
print(job.job_id)
# => 50
```

このCSVアップロードは非同期で処理されますので、完了まで待ちます。

```py
while job.finished() == False:
	print(job.status) # => STARTED
	# 処理待ち
	time.sleep(5)
```

完了したら、取り込みエラーがあったかを確認できます。

```py
print(job.total_count)
# => 200
print(job.success_count)
# => 198
print(job.failed_count)
# => 2
```

もしエラーがあれば、その原因を記したファイルをダウンロードできます。この内容はZipコンテンツなので、ダウンロード先のファイル名は `.zip` にしておくのが良いでしょう。

```py
job.download_error_file('result.zip')
# => True
```

例えば以下のようなエラーが書かれています。

```csv
"エラーメッセージ","email","__prop1__","__prop2__","__prop3__"
"[email: [sample1@example: 無効なEメールアドレス形式です。]]","sample1@example","サンプル","サンプル次郎","20210101"
```

## 送信

送信は `send` メソッドになります。返値はデリバリーIDになります。このデリバリーIDで、メールの送信状況や配信停止などを行います。

```py
try:
	# 送信
	delivery_id = bulk.send()
	print(delivery_id)
	print(bulk.delivery_id) # こちらも可
except Exception as e:
	# APIエラー
	print(e)
```

### 配信状況を知る

もし配信状況が知りたい場合には `get` メソッドを実行してください。これでメールの配信状況を取得します。すでに配信予約になっていると RESERVE といった文字列が返ってきます。

```py
bulk.get()
print(bulk.status)
# => RESERVE
```

## まとめ

Python SDKを使えばWebアプリケーションはもちろん、機械学習やIoTと組み合わせてblastengineを活用してもらえます。バルクメールは大量の宛先に対して一括配信を行うのに便利です。50件を超える宛先を指定する場合にはCSVアップロードを活用してください。

ぜひblastengineのPython SDKを活用ください！

[blastengine · PyPI](https://pypi.org/project/blastengine/)
blastengineのPython SDKを使ってメールを一括配信する

blastengineはエンジニアフレンドリーなメール配信サービスです。APIとSMTPリレーの両方をサポートしており、手軽に素早くメール配信ができるようになっています。

今回はPythonでblastengineのAPIを簡単に使えるSDKを開発しましたので、使い方を紹介します。現在はトランザクションメール（即時発信メール）とバルクメール（一括配信）をサポートしています。[トランザクションメールの使い方はこちらの記事で紹介しています](https://qiita.com/goofmint/items/f89cc270fc21e6c2e89f)。今回は一括配信の使い方を解説します。

## インストール

インストールはpipコマンドで行ってください。

```
pip3 install blastengine
```

## インポート

クライアントとバルクをインポートします。

```py
from blastengine.Client import Blastengine
from blastengine.Bulk import Bulk
```

## 初期化

Blastengineを初期化します。ユーザ名とAPIキーを使います。

```py
# 初期化
Blastengine('USER_NAME', 'API_KEY')
```

## メールオブジェクトの用意

バルクメールは `Bulk` を使います。件名やテキスト本文などを指定します。 `__name__` となっているのは、配信先ごとに置き換えられる文字列になります。

```py
# バルク（一括発送）メールオブジェクトの作成
bulk = Bulk()
# 情報を適用する
bulk.subject('メールの件名')
# __name__ は置き換えられる文字列
bulk.text_part('テキスト本文 __name__')
# 2つ目の引数（名前）はなくても大丈夫です
bulk.fromAddress('info@example.jp', '管理者')
```

### 添付ファイルの追加

添付ファイルは `attachments` メソッドで、ファイルのパスを指定してください。

```py
# 添付ファイルがある場合
bulk.attachments('./test.py')
bulk.attachments('./image.png')
```

### 一度保存する

このメールテンプレートができた段階で一度保存します。

```py
try:
	bulk.begin()
except Exception as e:
	# APIエラー
	print(e)
```

## 宛先を設定する

次に宛先を設定します。この時、置き換え文字列を設定できます。

```py
bulk.to('user1@example.com', [{
	'__name__': 'User1'
}])
bulk.to('user2@example.com', [{
	'__name__': 'User2'
}])
```

宛先を設定したら、保存を行います。

```py
bulk.update()
```

## 送信

送信は `send` メソッドになります。返値はデリバリーIDになります。このデリバリーIDで、メールの送信状況や配信停止などを行います。

```py
try:
	# 送信
	delivery_id = bulk.send()
	print(delivery_id)
	print(bulk.delivery_id) # こちらも可
except Exception as e:
	# APIエラー
	print(e)
```

### 配信状況を知る

もし配信状況が知りたい場合には `get` メソッドを実行してください。これでメールの配信状況を取得します。すでに配信予約になっていると RESERVE といった文字列が返ってきます。

```py
bulk.get()
print(bulk.status)
# => RESERVE
```

## まとめ

Python SDKを使えばWebアプリケーションはもちろん、機械学習やIoTと組み合わせてblastengineを活用してもらえます。バルクメールは大量の宛先に対して一括配信を行うのに便利です。

ぜひblastengineのPython SDKを活用ください！

[blastengine · PyPI](https://pypi.org/project/blastengine/)
blastengineのPython SDKを使ってメールを即時配信する

blastengineはエンジニアフレンドリーなメール配信サービスです。APIとSMTPリレーの両方をサポートしており、手軽に素早くメール配信ができるようになっています。

今回はPythonでblastengineのAPIを簡単に使えるSDKを開発しましたので、使い方を紹介します。現在はトランザクションメール（即時発信メール）のみサポートしています。

## インストール

インストールはpipコマンドで行ってください。

```
pip3 install blastengine
```

## インポート

クライアントとトランザクションをインポートします。

```py
from blastengine.Client import Blastengine
from blastengine.Transaction import Transaction
```

## 初期化

Blastengineを初期化します。ユーザ名とAPIキーを使います。

```py
# 初期化
Blastengine('USER_NAME', 'API_KEY')
```

## メールオブジェクトの用意

トランザクションメールは `Transaction` を使います。件名やテキスト本文、宛先などを指定します。

```py
# トランザクション（即時発送）メールオブジェクトの作成
transaction = Transaction()
# 情報を適用する
transaction.subject('メールの件名')
transaction.text_part('テキスト本文')
# 2つ目の引数（名前）はなくても大丈夫です
transaction.fromAddress('info@example.jp', '管理者')
# 宛先は1回に1アドレスです
transaction.to('user1@example.com')
# CC/BCCも同様です
transaction.cc('cc@example.com')
transaction.bcc('bcc@example.com')
```

## 添付ファイルの追加

添付ファイルは `attachments` メソッドで、ファイルのパスを指定してください。

```py
# 添付ファイルがある場合
transaction.attachments('./test.py')
transaction.attachments('./image.png')
```

## 送信

送信は `send` メソッドになります。返値はデリバリーIDになります。このデリバリーIDで、メールの送信状況や配信停止などを行います（トランザクションメールは即時配信されるので停止できません）。

```py
try:
	# 送信
	delivery_id = transaction.send()
	print(delivery_id)
except Exception as e:
	# APIエラー
	print(e)
```

## まとめ

Python SDKを使えばWebアプリケーションはもちろん、機械学習やIoTと組み合わせてblastengineを活用してもらえます。監視カメラ的なデバイスから、撮影された画像を添付してメールするのも容易でしょう。

ぜひblastengineのPython SDKを活用ください！

[blastengine · PyPI](https://pypi.org/project/blastengine/)
rhelメモ

rhelメモ（自分用）
## NW設定
動作環境：CentOS7.8

- 設定ファイル編集
条件：DHCP→静的IP
【設定】
✕bootproto=non
〇bootproto=static
【再読み込み】
✕nmcli connection reload
　nmcli connection up connection_name
https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/networking_guide/sec-configuring_ip_networking_with_ifcg_files
〇systemctl restart network
https://sourceexample.com/article/jp/9cdb3fd4b013c92f2d171fb167009377/
【確認】
ip a (IP addr)

【参考】

https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/networking_guide/sec-configuring_ip_networking_with_ifcg_files

https://it-kyujin.jp/article/detail/1104/

https://qiita.com/gomi_ningen/items/baee5fada818a8ba944a
【備忘録】Rubyの実行方法と標準出力メソッドの違いについて

## はじめに
本記事は、[Rubyがミニツク](http://www.minituku.net/)の学習内容をまとめたものです。
今回は、Ruby入門コースの1章をやります。

## まとめ
* Rubyのプログラムを実行する方法は幾つかあり、代表的な方法として以下の手法がある。
・rubyコマンド
・irb
・-eオプション

* 標準出力のメソッドには、主に3種類ある。各メソッドには、次のような違いがある。
・print: 最後に改行を行わない。
・puts: 最後に改行を行う。
・p：　最後に改行を行う。文字列を出力する場合は""で囲まれる。

## Rubyのプログラムを実行する方法
・rubyコマンド
・irb
・-eオプション

まずは、自分の環境にRubyがインストールされているか確認する。
```:ターミナル
$ ruby -v
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-darwin20]
```

#### 方法１ rubyコマンドで実行する
テキストエディタを用いて、以下のプログラムを作成し保存する。
その際、ファイル名は「hello_ruby.rb」とする。
```ruby:hello_ruby.rb
# frozen_string_literal: true

puts('Hello, Ruby!')
```

そして、保存したファイルがあるディレクトリでrubyコマンドを実行する。実行結果として、`Hello, Ruby!`が表示されていればOKです。
```:ターミナル
$ ls
hello_ruby.rb

$ ruby hello_ruby.rb 
Hello, Ruby!
```

#### 方法2 irbを起動する
irbとは、「interactive Ruby」（対話式Ruby）の略称で、1行ずつRubyの実行結果を表示してくれるライブラリのこと。
コマンドラインに「irb」と入力することで起動でき、終了するときには「exit」もしくは「quit」と入力する。

```:ターミナル
$ irb
irb(main):001:0> puts('Hello, Ruby!')
Hello, Ruby!
=> nil
irb(main):002:0> exit
```

#### 方法3 -eオプションを用いる
irbを起動せず、簡単なプログラムを確かめたい時には、rubyコマンドに-eオプションを付け、プログラムを渡すと実行することができる。

```:ターミナル
$ ruby -e 'puts("Hello, Ruby!")'
Hello, Ruby!
```

## 端末に表示する(標準出力のメソッド)
#### printメソッド
引数で渡された値を端末に表示するメソッド。最後に改行を行わない。改行を行いたい場合は、`\n`を文字列内に加える。

```:ターミナル
$ irb                            
irb(main):001:0> print('Hello, Ruby!')
Hello, Ruby!=> nil
irb(main):002:0> puts('Hello, Ruby!')
Hello, Ruby!
=> nil
irb(main):003:0> puts("Hello, Ruby!\n")
Hello, Ruby!
=> nil
※　　"\n"　のようなバックスラッシュ記法を文字列に含む場合、文字列はダブルクォーテーション("")で囲む。

```

#### putsメソッド
引数で渡された値を端末に表示するメソッド。最後に改行を行う。引数が複数渡された場合は、それぞれの引数の最後に改行を入れて、表示する。

```:ターミナル
$ irb                            
irb(main):001:0> puts("Hello", ",", "Ruby", "!")
Hello
,
Ruby
!
=> nil
```

#### pメソッド
printメソッドやputsメソッドのように引数を端末に表示する。オブジェクトごとに人が見てもわかりやすい形で表示してくれる。
・文字列：""(ダブルクォーテーション)で囲まれて表示される
・数字：そのまま表示される

```ruby:hello_ruby.rb
# frozen_string_literal: true

puts 'putsで文字列の12345を出力'
puts '12345'
puts 'putsで数字の12345を出力'
puts 12345
puts 'pで文字列の12345を出力'
p '12345'
puts 'pで数字の12345を出力'
p 12345
```

```:ターミナル
$ ruby hello_ruby.rb
putsで文字列の12345を出力
12345
putsで数字の12345を出力
12345
pで文字列の12345を出力
"12345"
pで数字の12345を出力
12345
```


## 参考
[Rubyがミニツク](http://www.minituku.net/)
[オブジェクト指向スクリプト言語 Ruby リファレンスマニュアル](https://docs.ruby-lang.org/ja/latest/doc/index.html)
[Unity] The referenced script (Unknown) on this Behaviour is missing! の対策

:::note warn
The referenced script (Unknown) on this Behaviour is missing!
The referenced script on this Behaviour (Game Object 'hoge') is missing!
:::
というような警告が表示された際に、問題となっている GameObject を抽出する方法です。

## ① 下記スクリプトをプロジェクトに配置
```ruby:MissingComponent.cs
using UnityEditor;
using UnityEngine;

public class MissingComponent {
	[MenuItem("Tools/Find Missing Components")]
	public static void Find() {
		Debug.Log("Start Find Missing Components.");
		bool isFind = false;
		GameObject[] instances = Resources.FindObjectsOfTypeAll(typeof(GameObject)) as GameObject[];
		foreach (var instance in instances) {
			int count = GameObjectUtility.GetMonoBehavioursWithMissingScriptCount(instance);
			if (count > 0) {
				Debug.LogError("Failed!! Find Missing Component in Scene. name=" + instance.gameObject.name);
				isFind = true;
			}
		}
		string[] prefabGUIDs = AssetDatabase.FindAssets("t:prefab");
		foreach (var prefabGUID in prefabGUIDs) {
			string path = AssetDatabase.GUIDToAssetPath(prefabGUID);
			GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
			int count = GameObjectUtility.GetMonoBehavioursWithMissingScriptCount(prefab);
			if (count > 0) {
				Debug.LogError("Failed!! Find Missing Component in Prefab. name=" + prefab.gameObject.name);
				isFind = true;
			}
		}
		if (isFind == false) {
			Debug.Log("Success!! Not found missing components.");
		}
	}
}
```
## ② UnityEditor のメニューから、Tools/FindMissingComponents を押す

Missing なコンポーネントを含んだ GameObject の名前が Console に出力されるので、
それをヒントに当該 GameObject から Missing を Remove するなどの適切な対応をとる。
メールサーバ運用で問題になるドメインレピュテーション/IPレピュテーションとは

メールサーバを運用している中でよく問題に上がるのがメールの不達です。メールが届かないとECサイトの通知が確認できなかったり、仕事上の連絡ができない、メルマガなどの購読率が落ちるといった問題が起きます。

メールの不達にはいくつかの原因があります。

- 個人や組織の迷惑メール設定に入ってしまっている
- DMARC/DKIM/SPFなどのなりすまし対策を行われていない
- ドメインレピュテーション/IPレピュテーションが低い

## 個人や組織の迷惑メール設定に入ってしまっている

Gmailなどのメールサービスでは迷惑メールフィルタリング機能があります。個人で設定できるものもあれば、企業のシステム管理者による設定も行われています。このフィルタリングに引っかかって、受信ボックスに入っていないケースはよくあります。

携帯電話ではキャリア側の設定でブロックされてしまうケースもよくあります。携帯電話の場合、ドメインや送信者アドレスごとに受信可否を設定しないといけない場合があります。

フィルタリングに引っかかる条件は過去の迷惑メールの学習結果によるものなので、迷惑メールと誤認されない（リンクが多すぎない、怪しい文面を避けるなど）ような対策が必要です。携帯電話の場合は、受信設定が必要になるので、メールの送信アドレスを明記して受信設定を依頼しましょう。

## DMARC/DKIM/SPFなどのなりすまし対策を行われていない

DMARCやDKIM、SPFは基本的になりすまし防止のドメイン認証技術になります。DNSやメールのヘッダー内に認証情報を埋め込み、サーバ側でDNSに問い合わせて確認することで正しいメール送信元であることを保証します。シンプルに設定できるものから、より複雑なものまで複数あります。

最近Gmailが対応したBIMIもなりすまし防止技術の一つになります。

## ドメインレピュテーション/IPレピュテーションが低い

最後がドメインレピュテーション/IPレピュテーションになります。レピュテーションは信頼度になります。ドメインやIPアドレスごとに信頼度があり、信頼度が低いと判断されるとブラックボックスに追加されます。ブラックボックスに登録されると、受信ボックスに届けるのは難しいでしょう。

ドメインレピュテーションは、新しいドメインであればゼロの状態ではじまっています。スパムメールを送れば、徐々にレピュテーションは下がっていきます。この時問題になるのは中古ドメインを購入した場合でしょう。一度解放されたドメインを購入した場合に、すでにレピュテーションが低い可能性があります。

IPレピュテーションはクラウドサービスで問題になります。インスタンスを立ち上げるたびにIPアドレスを手軽に変更できてしまうため、スパムメール送信でよく利用されていました。その結果、新しいインスタンスを立ち上げたのに、ブラックボックスに登録されていることも少なくありません。

ドメインレピュテーション/IPレピュテーションをチェックするには次のようなサイトで入力してみると良いでしょう。

- [Sender Score](https://senderscore.org/)
- [BarracudaCentral.org](https://www.barracudacentral.org/lookups)
- [Email Blacklist Check](https://mxtoolbox.com/blacklists.aspx)
- [IP Blacklist Check](https://dnschecker.org/ip-blacklist-checker.php)
- [Mail Blacklist Checker](http://mail-blacklist-checker.online-domain-tools.com/)
- [Email Blacklist Check](https://www.debouncer.com/blacklistlookup)
- [Check Single URL](https://www.trustedsource.org/)
- [Postmaster Tools](https://www.gmail.com/postmaster/)
- [Smart Network Data Services](https://sendersupport.olc.protection.outlook.com/snds/)

すべてのWebサイトでチェックする必要はないと思いますが、サービスによって判定基準が異なるので、複数のサービスで安全なドメイン、IPアドレスであることを確認するのをおすすめします。

## 回避策

回避策としては、先に挙げた内容の逆を行うのが基本です。

1. DMARC/DKIM/SPFなどのなりすまし対策を行う
2. ドメインレピュテーション/IPレピュテーションの高いものを使う
3. 迷惑メール判定されないように気をつける（内容や送信頻度など）

そしてメール送信サービスを使うのも一つの解決手段です。私たちの提供する[blastengine - ブラストエンジン](https://blastengine.jp/)もその一つになります。SMTPリレーサービスを提供していますので、既存のSMTP経由でのメール送信をほぼそのままに移行が可能です。信頼度の高い送信元として、確実に受信ボックスへメールを届けられます。

## まとめ

せっかくメールを送信しても、受信ボックスに届かなければ意味がありません。しかもメールは相手のシステム内に送られるので、本当に届いているかを判断するのが難しいでしょう。適切な対策を行い、メールの不達を防止しましょう。
深層学習モデルを図示する方法５選

書籍や解析サイトでよく見かけるディープラーニング・モデルの構成図、どうやって描いているのでしょう？
Sketchなどを使ってガチで作るのも良いですが、正直ほとんど決まりきった作業なので面倒。

探してみると、やはり、というか偉大な先人たちが用意してくれているライブラリ（ツール）がありました。

論文を書いたりするのに役立ちそうだし、自分で理解するのにも良いと思います。

## hiddenlayer

https://github.com/waleedka/hiddenlayer

非常にシンプルな略図が作れる
PyTorchモデルから変換できる

## convnet-drawer

https://github.com/yu4u/convnet-drawer

ズバリ、論文などで見かける3D表示のアレが作れる
Kerasモデルから変換できる

## NN SVG
http://alexlenail.me/NN-SVG/AlexNet.html
 
インタラクティブに作れて、グリグリ回してSVGに保存ができるタイプ
クラシックなノードを線で接続したタイプ、LeNet風のタイプ、CNNに適した3D(AlexNet)タイプから選べる
こういうのが一番好き！
もしかするとディープラーニング本の挿絵ってこれが使われているのかも知れない・・・

## draw_convnet

https://github.com/gwding/draw_convnet

これも論文や書籍で見られる2D表示の図を作ってくれるライブラリですが、いかんせんちょっと古い。
外観は論文風です。

## TensorSpace.js
https://tensorspace.org/index.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676310/2a3e9087-da65-cad4-5328-c60605ace2ab.png)


これは極め付け
かなりSFチックなド派手なビジュアライゼーションです。
ブラウザ上で動作します。
モデル構成だけでなく、実際の学習の様子も確認できます。
こう言った大袈裟な（？）ビジュアル化って好き嫌いが分かれると思いますが、私は好きな方です。
何でもカッコいい方が良いじゃないですか？
積み重なった立方体をダブルクリックするとそれぞれのレイヤが展開されて表示される、など凝った演出もあり、頭の中のイメージが具現化されるような感動を覚えました。
ただ設定はそこそこ大変そうです。

以上、ただ紹介しただけで特にコレは！というのはありませんが、まあ色々触って遊んでみてください！
[Flutter]デプロイゲートでAndroidのプロジェクト名を変えるには

AndroidManifestのlabel名を変更すればOKです。

ディレクトリの場所はこちら。

    アプリ名/android/app/src/main/AndroidManifest.xml

![スクリーンショット 2022-08-22 17.26.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494487/e51bd2fc-3f2d-fea4-1328-70c96387d58f.png)

Flutter側のプロジェクト名を変更したのに、なぜか変わらないなーって思って調べたらこんな単純なことでした。

どなたかの参考になれば幸いです。
InputFieldに入力された文字から空白と改行を消したい

## 課題

UnityのInputField(SingleLine)では改行なんて入力されないだろ…と思って作っていたものの
たまに改行コードが入力された名前がDBに登録されていることがあった。


コピペで入れたのか？
Androidのキーボードだと入力できたりするのか？

入力された方法はともかく、このままだと名前一覧をcsv等にエクスポートするときに不都合となる。
サーバ側はサーバ側でデータ受取時に対処するらしい。偉い。
クライアント側でもある程度対処しておきたい。



## コード

```csharp

        public static string 空白と改行を消す(string str)
        {
            return str.Replace("\r", "").Replace("\n", "").Trim();
        }

```


## 参考

### String.Trim()
https://docs.microsoft.com/ja-jp/dotnet/api/system.string.trim?view=net-6.0

### 【C#】文字列内の改行文字を削除した文字列を返す拡張メソッド

https://baba-s.hatenablog.com/entry/2015/01/16/102513
今日の発掘動画：Linuxのブートプロセスとsystemd

　・「ブートプロセス」を徹底理解 #11【ウズウズカレッジ】
　　　　https://www.youtube.com/watch?v=MHKrf4x8ibw
　・（英）UEFI boot explained (for Linux users)【Root Labs】
　　　　https://www.youtube.com/watch?v=-V3VhP-MUwE

UEFIのLinuxのブートプロセスとsystemdについての解説。

ちなみに、レガシーBIOSに関するブートプロセスは違うらしい。
これに関しては、『ブートの仕組み』
　　http://nobusan.jp/computer/boot/boot.html
が有名とのこと。

※ youtube 日本語自動翻訳
　　https://www.google.com/search?q=youtube+自動翻訳+日本語

-------
【情報・工学】青レンの良質解説動画 発掘一覧
　　https://qiita.com/aokiren8/items/965746f13ce27cb65ffa
Dart 初級 String.fromCharCodesでアルファベット出力

[String.fromCharCodes constructor](https://runebook.dev/ja/docs/dart/dart-core/string/string.fromcharcodes)
```
String.fromCharCodes(
Iterable<int>charCodes, [int start = 0, int? end])
```
指定された `charCodes` を含む新しい文字列を割り当てます。

`charCodes` は、`UTF-16コードユニット`とルーン文字の両方にすることができます。char-code値が16ビットの場合、コード単位として使用されます。

なんのこっちゃ、という事でとりあえずコード書いて`print(出力)`してみました。

```dart
print(String.fromCharCodes('A'.codeUnits));
// A;
```
`'A'`のみだと、`int型`にしなさいとエラーがでるので`UTF-16 コード単位`である`codeUnits,codeUnitAtメソッド`を付与していきます。まずは、`start`と`end`の変数にラテン語`A`と`Z`のコードユニットをいれて`for文`で`A~Z`を出力してみます。
```dart
int start = 'A'.codeUnitAt(0);
int end = 'Z'.codeUnitAt(0);
print(String.fromCharCodes([for (var i = start; i <= end; i++) i]));
// ABCDEFGHIJKLMNOPQRSTUVWXYZ
```
次に、変数にラテン語`A`のコードユニットを入れて、`イテレータ（処理を抽象化）`を使用し走査する `Iterable.generateコンストラクタ`で`Z`まで出力してみます。
```dart
int a = 'A'.codeUnitAt(0);
print(String.fromCharCodes(new Iterable.generate(26, (x) => a + x)));
// ABCDEFGHIJKLMNOPQRSTUVWXYZ
```
更に、`A`から`Z`の文字コードの番号`65`を利用して同じように出力してみます。
```dart
List<int> list = new List<int>.generate(26, (int index) => index + 65);
String a = String.fromCharCodes(list);
print(a);
// ABCDEFGHIJKLMNOPQRSTUVWXYZ
```
`A` `B` `C`と連結せずに一文字ずつ`for文`で出力してみます。
```dart
for(int i = 0; i <= 25; i++){
    print(String.fromCharCode(i + "A".codeUnitAt(0)));
  }
// A B C D E F G H I J K L M N O P Q R  S T U V W X Y Z
```
同じく、`for文`で`コード単位`をループ。
```dart
for (int s = "A".codeUnitAt(0); s <= "Z".codeUnitAt(0); s++) {
    print(String.fromCharCode(s));
  }
// A B C D E F G H I J K L M N O P Q R  S T U V W X Y Z
```
変数で始まりと終わりをもとめて、`while文`で終わりを知らせて出力。
```dart
int start = "A".codeUnitAt(0);
int end = "Z".codeUnitAt(0);
while (start <= end) {
    print(String.fromCharCode(start));
    start++;
  }
// A B C D E F G H I J K L M N O P Q R  S T U V W X Y Z
```
最後にこちらの配列を`A,B,C`に変えてみます。
```dart
var list = [for (var i = 0; i < 26; i++) i ];
var list = [for (var i = 0; i <= 25; i++) i ];
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
```
配列の長さと構造がわかっているので`List.generate`を利用し、ループさせます。
```dart
var list = List.generate(26, (int index) =>
    String.fromCharCode(index + 'A'.codeUnits[0]));
print(list);
// [A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z]
```
以上です、ご参考までに。
vscodeにアプデ(version 1.70)で加わったマージエディタ(3-way merge editer)を元に戻す方法

2022年7月の[アプデ](https://code.visualstudio.com/updates/v1_70)で加わったマージエディタ（3-way merge editer）ですが、GUIがガラッと変わってしまってミスが多発したのでアプデ前のGUIに戻すことにしました。
簡単に戻せたのでその共有です。

# 対処方法
## GUI設定から
1. Ctrl+Shift+p(macの場合はCmd+Shift+p)でコマンドパレットを開く
2. 「open setting」と入力し、`Preferences: Open User Settings`を開く
![コマンドパレット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619726/405d362e-f99f-45a3-6df3-8578c5ec3705.png)
3. 「merge」を検索し、`Git: Merge Editer`のチェックを外す
![設定でmergeを検索](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619726/65d0ba13-551c-9672-9cd1-533282e3ca29.png)

## setting.jsonから
```json:setting.jsonに追加
{
  "git.mergeEditor": false
}
```

# おわりに
好まない人が多いみたいですね。。。
https://github.com/microsoft/vscode/issues/157361
【WIP】find/ find_by/whereの違い

## バージョン
- Ruby 2.6.6
- Rails 6.0.3

## find/ find_by/whereの違い

### find
- 検索条件に引っかかる場合
``` ruby
pry(main)> Book.find_by(1)

Book Load (0.2ms)  SELECT `books`.* FROM `books` WHERE `books`.`id` = 1 LIMIT 1
=> #<Book id: 1, name: "名前", title: "タイトル", created_at: "2022-01-01 11:11:11", updated_at: "2022-01-01 11:11:11"> 
```

```ruby
pry(main)> Book.find(1).id     ## データの中身を取得するとき
=> 1
```


- 検索条件に引っかからない場合
  - ``ActiveRecord::RecordNotFound``が発生 
```ruby
pry(main)> Book.find(1000)
  Book Load (0.3ms)  SELECT `books`.* FROM `books` WHERE `books`.`id` = 1000 LIMIT 1
ActiveRecord::RecordNotFound: Couldn't find Book with 'id'=1000
```

### find_by
- 検索条件に引っかかる場合
``` ruby
pry(main)> Book.find_by(id: 1)

Book Load (0.2ms)  SELECT `books`.* FROM `books` WHERE `books`.`id` = 1 LIMIT 1
=> #<Book id: 1, name: "名前", title: "タイトル", created_at: "2022-01-01 11:11:11", updated_at: "2022-01-01 11:11:11"> 
```

```ruby
pry(main)> Book.find_by(id: 1)     ## データの中身を取得するとき
=> 1
```

- 検索条件に引っかからない場合
  - ``nil``を返す 
```ruby
pry(main)> Book.find_by(id: 1000)
  Book Load (0.2ms)  SELECT `books`.* FROM `books` WHERE `books`.`id` = 1 LIMIT 1
=> nil
```

### where
- 検索条件に引っかかる場合
``` ruby
pry(main)> Book.where(id: [1, 2])

Book Load (0.2ms)  SELECT `books`.* FROM `books` WHERE `books`.`id` IN (1, 2)
=> [#<Book id: 1, name: "名前1", title: "タイトル1", created_at: "2022-01-01 11:11:11", updated_at: "2022-01-01 11:11:11">,
#<Book id: 2, name: "名前2", title: "タイトル2", created_at: "2022-01-01 11:11:11", updated_at: "2022-01-01 11:11:11">]
```

```ruby
pry(main)> Book.where(id: [1, 2])[0].id    ## データの中身を取得するとき（戻り値は配列）
=> 1
```

- 検索条件に引っかからない場合
  - ``空の配列[]``を返す
```ruby
pry(main)> Book.where(id: １０００)
  Book Load (0.2ms)  SELECT `books`.* FROM `books` WHERE `books`.`id` = 1000
=> []
```
Visual Studio(≠Code)でAzure App Service+MySQL in Appアプリを公開するまでと参考にしたサイト 

Azure App Service と MySQL in App(というかMySQL自体)が初めてだったのでメモ。
基本的なAzure App Serviceの操作は↓で確認した(チュートリアルと違ってSQL Server使ってないけど)。

Azure App Serviceチュートリアル:Azure SQL Database を使用して Azure に ASP.NET アプリをデプロイする：[https://docs.microsoft.com/ja-jp/azure/app-service/app-service-web-tutorial-dotnet-sqldatabase](https://docs.microsoft.com/ja-jp/azure/app-service/app-service-web-tutorial-dotnet-sqldatabase)

## 1.Visual Studio 2022インストール
→公式([https://visualstudio.microsoft.com/ja/vs/](https://visualstudio.microsoft.com/ja/vs/))からDLしてポチポチしただけなので参考サイトなし。

## 2.Azureアカウント作成
→公式([https://azure.microsoft.com/](https://azure.microsoft.com/))でポチポチのみ。

## 3.ローカル用MySQLインストール(Windows)
→↓を見てポチポチ。
+ MySQLインストール：[https://www.javadrive.jp/mysql/install/](https://www.javadrive.jp/mysql/install/)

## 4.ローカル用MySQL設定
→MySQL in Appってユーザー：azure、パスワード：passwordなんか。
→じゃローカル環境も同じにしとこ。
→と思ったらパスワードポリシー設定に一手間いった。
+ MySQL 8.0 で validate_password を有効化・無効化する方法：[https://qiita.com/_meki/items/5f642e609ce99c1b727e](https://qiita.com/_meki/items/5f642e609ce99c1b727e)
+ MySQL8.0で4文字パスワードを許可：[https://qiita.com/11ohina017/items/481b1fe371f1e409dec7](https://qiita.com/11ohina017/items/481b1fe371f1e409dec7)

## 5.MySqlConnectorインストール
→ADO.NET何つかお(EntityFrameworkはあまり好きじゃない)
→ググったら「MySQL Connector/NET」ってあったけどライセンスがGPLか。
→「MySqlConnector」ならMITライセンスやん。こっち使お。
→Nugetポチ
+ MySQL用ADO.NETでConnectorと付く物は2つある：[https://qiita.com/noobow/items/cd5f776118562c66e73d](https://qiita.com/noobow/items/cd5f776118562c66e73d)

## 6.ローカル環境でHelloWorld
→VSポチポチで完了。

## 7.DBメンテナンス
→色々やってたらDB上のテストデータ増えたので一回全Deleteかけよ。
→MySQLワークベンチで1175エラー
→フールプルーフ解除コマンドが必要

+ MySQLワークベンチでupdate文を実行すると1175のエラーが発生：[https://yoneyore.hatenablog.com/entry/2016/01/05/200047](https://yoneyore.hatenablog.com/entry/2016/01/05/200047)

## 8.デプロイ
→色々調べたけど、結局Visual Studio 2022の発行機能(VSにAzureのアカウント紐付けとけばポチポチするだけ)が強力だったのでCLとか使わず。

## 9.MySQL in Appへの接続
→あれ、IDとPWはあってるはずなのに何故かMySQL in Appに繋がらん…
→ポート指定もあるので接続文字列は環境変数から取らないといけなかった。

+ ASP.NET CoreでMySQLを使ってみる -Web Appsにデプロイ：[https://sublimer.hatenablog.com/entry/2019/12/19/185522](https://sublimer.hatenablog.com/entry/2019/12/19/185522)

## 10.アプリにAzureAD認証を付ける
→F1(無料)プランで使いたいから変なアクセス弾くように認証付けよう。
→Azureポータルポチポチだけで認証付けれた。
+ Azure AD ログインを使用するように App Service または Azure Functions アプリを構成する：[https://docs.microsoft.com/ja-jp/azure/app-service/configure-authentication-provider-aad](https://docs.microsoft.com/ja-jp/azure/app-service/configure-authentication-provider-aad)

## 11.ログインユーザーのID取得
→認証できたんなら「ようこそ！XXさん」みたいなのつけてみるかと思って調べてみたらリクエストヘッダに入ってた。
→認証APIアクセス用のトークンもあるからこれで詳細も取れるのか。
→このトークンでGraph API叩いてもうまくいかん(InvalidAuthenticationToken)…。別口で取るようにするか。

App Service の Azure Active Directory 認証でユーザ情報をサーバーサイドで取得する：[https://qiita.com/sunack/items/ab76956edba683e272e7](https://qiita.com/sunack/items/ab76956edba683e272e7)

Easy Auth の Tokenで Graph APIを呼び出す：[https://statemachine.hatenablog.com/entry/2018/07/06/095521](https://statemachine.hatenablog.com/entry/2018/07/06/095521)
→うまくいかん。トークン解析したらちゃんと「"typ": "JWT",」ってなってるんだけどなぁ…
【WIP】Railsの主要なファイルやディレクトリ

### Railsの主要なファイルやディレクトリ
|ファイル・ディレクトリ | 概要 |
|---|---|
|.ruby-version|rbenvなどを利用している場合、このファイル内容に記載されているバージョンのRubyを利用する|
|Gemfile|このプロジェクトで利用するgemファイルを定義したファイル|
|Gemfile.lock|Gemfileの依存関係を解決した結果を保存する|
|app/|主なアプリケーションコードを記述するディレクトリ|
|bin/|Railsアプリケーションを開発するために利用する実行コマンドを格納しているディレクトリ|
|config/|アプリケーションの動作に関する設定ファイルや格納するディレクトリ|
|db/|DBに関する設定を格納するディレクトリ|
|lib/|Rakeタスクなどアプリケーションから独立したコードを格納するディレクトリ|
|public/|静的コンテンツを配置するディレクトリ|
|test/|テストに関するソースコードをまとめるディレクトリ|

#### binディレクトリの内容
|ファイル・ディレクトリ | 概要 |
|---|---|
|.bundle|Bundlerを使う際のbundleコマンドのbinstub|
|rails|railsコマンドのbinstub|
|rake|rakeコマンドのbinstub|
|setup|Railsアプリケーションを実行可能にするためのセットアップ用スクリプト|
|spring|Springという開発用のアプリケーションプリローダー|
|webpack|フロントエンドで利用するwebpackをラップしたWebpackerを実行する|
|webpack-dev-server|フロントエンドのソースコードをホットリロードするためのサーバを起動する|
|yarn|フロントエンドで利用するパッケージマネージャーYarnを実行する|

### railsコマンドについて
|コマンド | 概要 |
|---|---|
|stats|ControllerやModelなどの行数などを集計したデータを表示する|

```ruby 
% rails stats  ## ↓出力例
+----------------------+--------+--------+---------+---------+-----+-------+
| Name                 |  Lines |    LOC | Classes | Methods | M/C | LOC/M |
+----------------------+--------+--------+---------+---------+-----+-------+
| Controllers          |   2900 |   2441 |      43 |     224 |   5 |     8 |
| Helpers              |     17 |     14 |       0 |       2 |   0 |     5 |
| Jobs                 |      7 |      2 |       1 |       0 |   0 |     0 |
| Models               |   2345 |   1890 |      70 |     188 |   2 |     8 |
| Mailers              |    243 |    202 |       4 |      25 |   6 |     6 |
| Channels             |      8 |      8 |       2 |       0 |   0 |     0 |
| JavaScripts          |    728 |    554 |       0 |      12 |   0 |    44 |
| JavaScript           |     12 |      4 |       0 |       0 |   0 |     0 |
| Libraries            |    114 |    101 |       3 |       7 |   2 |    12 |
+----------------------+--------+--------+---------+---------+-----+-------+
| Total                |   6374 |   5216 |     123 |     458 |   3 |     9 |
+----------------------+--------+--------+---------+---------+-----+-------+
  Code LOC: 5216     Test LOC: 0     Code to Test Ratio: 1:0.0
```
お客に技術用語を使って話してしまう技術者の例 (エリック・エヴァンスのドメイン駆動設計より)

# 抜粋

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/3bf677dc-deb5-1595-7837-232af13ac773.png)


>ユーザ：したがって、通関地点を変更すると、経路計画を全部作り直さないといけません。
>
>開発者：わかりました。該当する貨物IDを持ったすべての行を輸送テーブルから削除してから、荷受け地と荷出し地、新しい通関地点を経路選択サービス（Service）に渡せば、テーブルにデータが再登録されます。貨物（Cargo）にブール値を持たせて、貨物テーブルにデータがあることがわかるようにしましょう。
>
>ユーザ：行を削除する？まあ、いいでしょう。とにかく、それまでに通関地点を一切入力していなくても、通関地点が変更されたら経路計画は作り直す必要があります。
>
>開発者：もちろんです。荷受け地や荷出し地、通関地点を変更（または初めて入力）したら、貨物データがあるかどうかを必ずチェックして、そのデータを削除してから、経路選択サービスに再生成させることになります。
>

# 「行を削除する？まあ、いいでしょう。」

こんなことを相手に言わせないようにしたいものだ。
スケジュール管理とアローダイアグラム

やるべきことをやるべき人がやるべき期間にできているかを適切に対策を行う。
それには図表を使う。
その図とは```ガンチャート```、```アローダイアグラム```が代表的。

# PERT（Program Evaluation and Review Technique)
作業の前後関係をアローダイアグラムで表す工程管理のための図法。

# アローダイアグラムの書き方
## ①
```作業の開始と終了```を表す記号。
結合点と呼ぶ。
丸の中の番号は先頭からの順を表す。
## →
矢印（```アロー```）と呼ぶ。
```線の上に作業名```
```線の下に作業日数```

## ---→
ダミー作業を表す矢印。
```２つ以上の作業```がある場合は、この矢印を使って新しい結合点に導き出す。

### 気づき
まだ見方がわからない。
これから勉強だ。

# 全体の日数はどこで見る？
p５１０の図を見る。
全体の日数は単純に８５日と思う。
しかし
作業の条件が加味されるとp５１１の図のように９０日かかることがわかる。

## 留意点
* 各作業に```必要な作業日数を順```に加算していく。
* 複数の作業が並行する箇所では、```より多く作業日数がかかる方の数字```を採用する。

# 最早（さいそう）結合点時刻と最遅（さいち）結合点時刻
## 最早結合点時刻
```もっとも早く作業を開始```できる日時のこと
いつから次の作業を始めることができるのか。

## 最遅結合点時刻
全体に影響を与えない範囲で、```最も開始を遅らせた時刻```のこと。
いつまでに作業開始しないといけないか。

### 気づき
範囲内であれば遅らせることができるのか。

# クリティカルパス
```全体のスケジュールを狂わせる結果```に即繋がってしまう要注意な経路。

全体の日数を求めた時の```最長ルートと同じ```。
このルート上の```結合点は、最早結合点時刻と最遅結合点時刻が同じ```になっている。

## 気づき
クリティカルパスの作業は仕事のできる人じゃないと任されないのか。

# スケジュール短縮のために用いる手法
```クラッシング```と```ファストトラッキング```がある。
## クラッシング
```資源を追加投入してコストの増大を最小限```に抑えながらスケジュールの所要期間を短縮する技法
例　作業する人を増やす
## ファストトラッキング
順番に実施されるアクティビティやフェースを```並行して遂行```するスケジュール短縮技法

# テストを解いた時の気づき
アローダイアグラムはまだ慣れていないから簡単に解けなかった。
mui チート・ブラウザの横幅に合わせて UI コントロールの横幅を調整する

- [あるWebサービスの開発メモ・目次ページに戻る](https://qiita.com/ishi32/items/152a1ecf7eeee7a8fb57)
- [あるWebサービスの開発メモ・mui チートに戻る](https://qiita.com/ishi32/items/99d9df23f5c9e5e75687)

### やりたいこと

- mui のコンポーネントの横幅をブラウザの横幅に応じて変化させたい

### mui が提供してくれる解決策その１

fullWidth を指定すると、そのコンポーネントはコンテナの全幅を使うようになります

しかしながら、本当にいっぱいまで使うため、実用上はまったく問題ないものの、レイアウト的には「デカすぎない？」という感じになってしまいます。

![スクリーンショット 2022-08-21 1.40.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539175/5f7e2d4c-4b48-b78c-5dfc-e6f1aff89520.png)

```
return (
  <>
    <Grid container spacing={2} justifyContent="center" alignItems="center">
      <Grid item xs={12}>
        <FormLabel>
          <Typography align="left" variant="body2">
            一覧表示用タイトル
          </Typography>
          <OutlinedInput
            required
            fullWidth
            value={stitle || ""}
            onChange={(e) => stitleHandleChange(e)}
          />
          <FormHelperText>ex.「sirokuro.site について」</FormHelperText>
        </FormLabel>
(snip)
```

- retuen の内側には複数のコンポーネントが配置されるため、全体をフラグメントで囲っている
- mui の公式では TextField の使用を推奨していると思われるが、TextField を使用した場合の挙動に問題があったため、FormLabel コンポーネントを使って、ラベル、入力フィールド、ヘルパーテキストを個別に指定するようにしている
- 入力フィールド (OutLinedInput) で fullWidth を指定して、コンテナ幅のギリギリまで最大限使うようになっている

### 解決策その２

この記事にいただいたコメントに従って実装を改めました

(ブラウザの横幅: 375px)

![スクリーンショット 2022-08-24 1.07.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539175/f9883334-141d-ff7d-678e-3b7dd703a3f2.png)

(ブラウザの横幅: 600px)

![スクリーンショット 2022-08-24 1.09.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539175/bcba36f5-8914-4dcb-b83d-67ac1bc21340.png)

(ブラウザの横幅: 1200px)

![スクリーンショット 2022-08-24 1.10.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539175/b3c4d1e2-6c55-5989-1704-8e613105106b.png)

```
<Container maxWidth={false}>
  <FormLabel>
    <Typography align="left" variant="body2">
      一覧表示用タイトル
    </Typography>
    <OutlinedInput
      required
      fullWidth
      value={stitle || ""}
      onChange={(e) => stitleHandleChange(e)}
    />
    <FormHelperText>ex.「sirokuro.site について」</FormHelperText>
  </FormLabel>
(以下同上)
```

- Container コンポーネントでそれ以下のコンポーネントを囲っている

[公式](https://mui.com/material-ui/react-container/)によると「Containerは、コンテンツを水平方向に中央揃えにします。 最も基本的なレイアウト要素です。」とありました。本当にこれだけでいい感じにレイアウトできるなんて、なんと素晴らしい！

コメントいただき、ありがとうございました
リリースノート タグ付け

デプロイ時毎回忘れるのでメモします。
## リリースノートのタグ付けコマンド

タグの一覧を見る
```
git tag
```

タグを作成する
```
git tag -a v1.3.0 -m "version 1.3.0"
```

タグを付ける
```
git push origin v1.3.0
```
【Flutter/Android】DartDefinesで、flavorをする

### FlutterのAndroidで、flavorをする場合、下記の２つある

* flutter_flavorizrを使う
* DartDefinesを使う

flutter_flavorizrは、コマンドで自動的にファイルを作成・変更を行ってくれるので楽なのですが、ファイルが複数出来たり、管理が煩雑になります。
DartDefinesは、手動でファイルを修正する必要がありますが、ファイルが増える訳ではないので、管理が楽になります。
今回は、DartDefinesでflavorを実現したいと思います。

### build.gradleを編集

```diff_gradle:app/build.gradle
...

def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
    flutterVersionName = '1.0'
}

+def dartDefines = [:]
+if (project.hasProperty('dart-defines')) {
+    dartDefines = dartDefines + project.property('dart-defines')
+            .split(',')
+            .collectEntries {
+                def pair = new String(it.decodeBase64(), 'UTF-8').split('=')
+                [(pair.first()): pair.last()]
+            }
+}
...
android {
...
    defaultConfig {
...
+        if (dartDefines.FLAVOR != 'prod') {
+            applicationIdSuffix ".${dartDefines.FLAVOR}"
+        }
+        resValue "string", "app_name", "アプリ名" + (dartDefines.FLAVOR == 'prod' ? '' : "(${dartDefines.FLAVOR})")
...
```

### AndroidManifest.xmlを編集

build.gradleで作成したapp_nameをandroid:labelを設定します。

```diff_xml:app/src/main/AndroidManifest.xml
   <application
-        android:label="アプリ名"
+        android:label="@string/app_name"
        android:name="${applicationName}"
```

###Android Studioのビルドを編集

ビルド環境を編集します。
Run/Debug Configurationsの「Additional run args」に書きを追加します。
```
--dart-define=FLAVOR=xxx
```
xxxを使用したいflavorを入力してください。

###デバッグを実行

デバッグでアプリ名が「アプリ名(xxx)」となっていれば成功しています。
かなり本気でチャート予測をやってみた話

#### はじめに
　フリーランスになってから、チャートを見て仕事をしたりしていたのですが、機械学習がある程度できるようになったので、チャート解析がどういうものかちょっとやってみようかなと思って、トライしてみました。~~本当はチャート見て仕事したらいけないのですが、、ゴメンナサイ（汗。~~ 個人的には、かなり本気でやったつもり。

#### 取り合えずやってみる
　チャートデータの標準化などを行って、取り合えず機械学習にかけてみる。今回は、次のローソク足が上か下かを予測してみました。データは、meta traderがpython用のapiを提供しているので、そちらから無料で取得できます。勿論、最初からそんなに簡単に上手くいくはずもなく、正解率は5割ちょっと。この辺りから、色々と試行錯誤が始まる。

#### 改善策
　モデルには、pytorchの深層学習モデルを使用しました。最初にモデルのノード数などを変えたりしてみたが、過学習が起こるだけで上手くいかない（どうも、モデルの問題ではないようだ）。なので、次の方法としてチャートデータの抽出を行ってみた。具体的には、荒場のチャートは除いて、綺麗そうなチャートのみで学習を行ってみました。チャートの抽出には、平均足との一致率なども考慮しました。

#### 結論
　かなりチャートを絞ってみたが、正解率に変化はなかった。まだ、絞り込みが足りないのかもしれない（または、絞り込み方を間違えているのか）。一応、チャート画像なども確認してみたが、それなりに綺麗ではあるが、まだ規則性は見つけにくい。
　中には、お手本の様な綺麗なチャートも僅かながらに含まれているが、こういったチャートのみを抽出できれば良いのかな？

#### 考察
　今のところ、正解率が上がらないのは、モデルではなく、データ側に原因があると考えている。~~まあ、当たり前と言われれば、その通り。~~ 簡単に言うと、同じ様な形状のチャートでも、次に上がる確率が50％、下がる確率が50％だと、モデルも正解率が50％だと言わざるを得ない（無理に予測させようとしても、過学習になるだけ）。
　なので、データを増やせば過学習も改善されるかと思ったけど、あまり変化はなかった。そのあたりは文献などもあったので、恐らくデータを増やしてもあまり変化はないのかもしれない。個人的には、モデルの予測確率はそこまであてにならない様な気もするんだけど、どうなんだろうな。

#### この先
　マシンスペックがそこまである訳でもないので、規則性が現れる様なチャート抽出が必要かなと思う。モデルはそこまで複雑ではなくても良い様な気もする。~~と言うか、抽出が上手くいけば、if文だけでも行ける様な。。~~ どの様なチャートを抽出すればよいかについては、正解は1つだけではないだろうし、ある程度、経験則がものを言いそうだ。
　あまり熱くなりすぎると深みにはまりそうなので、ぼちぼちマイペースでやってみる。一応、とても勉強にはなるので、一度くらいはトライしてみても良いかもしれない。

#### 補足
　因みに平均足の正解率なら７割くらいある。そして、平均足とローソク足の上下の一致率も７割くらいだから、0.7×0.7=0.49となり、やはり正解率は50%くらいになるのだ。よく出来ている。
mpstat を使って CPU コアの使用率を取得

CPU コアごとの使用率を数字で取得したい。

topコマンドを使うと、「t」-「t」-「1」で表示される。
```
top - 15:22:44 up 16 days, 21:07,  5 users,  load average: 0.18, 0.11, 0.06
Tasks: 212 total,   1 running, 211 sleeping,   0 stopped,   0 zombie
%Cpu0  :   1.7/1.0     3[                                                     ]
%Cpu1  :   2.7/0.7     3[                                                     ]
MiB Mem :   3747.8 total,    230.7 free,   1058.1 used,   2459.0 buff/cache
MiB Swap:   2048.0 total,   1104.2 free,    943.8 used.   2363.9 avail Mem 

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND  
    924 nanbuwks  20   0  497116  13412   4728 S   2.7   0.3 478:05.78 Xorg     
   1182 nanbuwks  20   0 3961512  73720  14468 S   2.3   1.9 644:43.25 gnome-s+ 
 254699 nanbuwks  20   0  731940  13576  11660 S   1.0   0.4 160:04.04 check-n+ 
     14 root      20   0       0      0      0 I   0.3   0.0  10:34.36 rcu_sch+ 
    628 root      20   0    2548     40      0 S   0.3   0.0  18:33.31 acpid    
   1165 nanbuwks  20   0  950656  52080   8016 S   0.3   1.4  95:50.11 node /h+ 
 182332 Debian-+  20   0   26888   6064   2696 S   0.3   0.2  13:31.30 snmpd    
 675961 root      20   0       0      0      0 I   0.3   0.0   0:00.61 kworker+ 
```
テキストコピペだと見えないけど、実際には CPU コアの使用率が以下のように白いグラフで表示されている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/bbe3bda1-200b-4707-0ebe-fe42cda9db6f.png)


この数字をスクリプトで取得したい。

top だといろんな数字がごちゃまぜになる。この数字だけ取得できないかな?・・・と思ったが意外と無い。

システムコールなども簡単に使えそうなものが無いっぽい。仕方なく、top のようなコマンドの出力をパースすることにした。

top, snmpwalk, sar などで取得できるが、今回は MPSTAT の出力をパースすることにした。

# 環境

- Ubuntu 20.04 ja LTS
- sysstat (mpstat) 12.2.0

# MPSTAT

パッケージ sysstat に含まれています。
インストール
```
$ sudo apt install sysstat
```

通常の表示

```
$ mpstat 
Linux 5.15.0-43-generic (nanbuwks-PRIMERGY-TX1310-M3) 	2022年08月22日 	_x86_64_	(2 CPU)

15時40分52秒  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
15時40分52秒  all    3.42    0.04    0.96    1.75    0.00    0.02    0.00    0.00    0.00   93.82
```

CPUコアそれぞれ表示
```
$ mpstat -P ALL
Linux 5.15.0-43-generic (nanbuwks-PRIMERGY-TX1310-M3) 	2022年08月22日 	_x86_64_	(2 CPU)

15時41分33秒  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
15時41分33秒  all    3.42    0.04    0.96    1.75    0.00    0.02    0.00    0.00    0.00   93.82
15時41分33秒    0    3.32    0.02    0.99    1.89    0.00    0.01    0.00    0.00    0.00   93.77
15時41分33秒    1    3.52    0.05    0.92    1.62    0.00    0.02    0.00    0.00    0.00   93.86
```

# 数字として取り出す

上のような出力から、AWK でデータを抜き出してみました。
まずは5行目の3番目のフィールド値、 CPU0 の %usr 値を取り出します。

```
$ mpstat -P ALL | awk 'NR==5 {print $3}'
3.32
```
うまく取れましたね。では usr 以外の負荷も合計した値を取り出したいので、100%から %idle を引いた値を取り出してみます。

```
$ mpstat -P ALL | awk 'NR==5 {print 100-$12}'
6.23
```

この値を zabbix-sender に取り込みたいので、整数値に直すようにしてみます。

```
$ mpstat -P ALL | awk 'NR==5 {print int(100-$12)}'
6
```


最初に変数 cpu に番号を入れるようにしてみました。

```
$ cpu=0; mpstat -P ALL | awk -v cpuno="$cpu" 'NR==cpuno+5 {print int(100-$12)}'
6
```

なお、-1を入れると CPUすべての総合値が出力されます。
```
$ cpu=-1; mpstat -P ALL | awk -v cpuno="$cpu" 'NR==cpuno+5 {print int(100-$12)}'
6
```
bundle install で `gem install mysql2 -v '0.5.3' --source 'https://rubygems.org/' と言われてうまくいかない

時間ないので、雑に忘備録として、一旦あげておきます

## 問題
```Gemfile
gem 'mysql2', '~> 0.5.3'
```

こんな感じでGemfileに`mysql2`を入れようとしたときに
```
bin/bundle install
```
って入れても
```
An error occurred while installing mysql2 (0.5.3), and Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.5.3' --source 'https://rubygems.org/'` succeeds before bundling.

In Gemfile:
  mysql2
```
こんなエラーが出るわけですよね。

書いてある通りに
```
gem install mysql2 -v '0.5.3' --source 'https://rubygems.org/
```
と入れても
```
ld: library not found for -lssl
```
こんな感じでエラーが出るわけです。。。

## 解決法
オプションで次のように記述すると解決できました。
```
gem install mysql2 -v '0.5.3' -- --with-ldflags=-L/usr/local/opt/openssl/lib --with-cppflags=-I/usr/local/opt/openssl/include
```
そしたら`bundle install`はうまくいくと思います。
`-v '0.5.3'`の部分は、自分のエラーに合わせたバージョンにするといいと思います。
例）バージョン0.5.1の場合→`gem install mysql2 -v '0.5.1' -- --with-ldflags=-L/usr/local/opt/openssl/lib --with-cppflags=-I/usr/local/opt/openssl/include`

```
bin/bundle install
...
...
...
Bundle complete! 46 Gemfile dependencies, 138 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
```
僕の場合はこんな感じでした。

## 環境
M1 Mac(2020)
Big Sur v.11.6.1

Rails 7.0.2.3
ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin20]


何か指摘があればお願いします。
ラズパイのDockerでpip install cryptographyが失敗する

## 問題
`pip install cryptography`が失敗する。
`cryptography`は`poetry`の依存ライブラリ。
imageは`python:3.9-slim-buster`

## 解決策
`cryptography`がRUSTコンパイラを使用しないバージョンを指定する。かつ依存ライブラリを`apt`でインストール。
環境変数 `CRYPTOGRAPHY_DONT_BUILD_RUST`に何でも良いので値をセットするとRUSTコンパイラを使わなくなる。

## Dockerfile
`poetry`を使ってPythonアプリを動かす例。

```Dockerfile
FROM python:3.9-slim-buster

ENV PYTHONUNBUFFERED 1
ENV CRYPTOGRAPHY_DONT_BUILD_RUST 1

WORKDIR /src

RUN apt update && apt install --no-install-recommends -y build-essential libffi-dev ca-certificates
python-cffi libssl-dev
RUN pip install cryptography==3.4.1
RUN pip install poetry
RUN mkdir /src/logs


COPY pyproject.toml* poetry.lock* ./
COPY app /src/app
COPY log_conf.yml ./
COPY env.sh ./


RUN poetry config virtualenvs.in-project true
RUN if [ -f pyproject.toml ]; then poetry install; fi

CMD ["poetry", "run", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80", "--reload", "-
-log-config", "log_conf.yml"]
```
PostgreSQL: ストアドファンクションの使い方

こちらのサンプルを改造しました。
[PostgreSQLで関数を作って、使う[PL/pgSQL入門]](https://qiita.com/SRsawaguchi/items/411801e254ee66f511f1)

city というデータベースに、ユーザー　scott でアクセスできるとします。

## テスト用のテーブルの作成

```sql:olympic.sql
DROP TABLE IF EXISTS host_cities;

CREATE TABLE host_cities (
  id SERIAL,
  name VARCHAR(255) NOT NULL,
  year INT NOT NULL
);

INSERT INTO host_cities(name, year) VALUES
  ('東京', 1964),
  ('メキシコシティ', 1968),
  ('ミュンヘン', 1972),
  ('モントリオール', 1976),
  ('モスクワ', 1980),
  ('ロサンゼルス', 1984),
  ('ソウル', 1988),
  ('バルセロナ', 1992),
  ('アトランタ', 1996),
  ('シドニー', 2000);
```

実行

```text
$ psql -U scott -d city < olympic.sql 
DROP TABLE
CREATE TABLE
INSERT 0 10
```

## ストアドファンクションの作成

```sql:years_ago.sql
DROP FUNCTION IF EXISTS years_ago(INTEGER);

CREATE OR REPLACE FUNCTION years_ago(year INTEGER)
RETURNS INTEGER AS $$
  BEGIN
    RETURN (extract(year from current_date)::INTEGER - year);
  END;
$$ LANGUAGE plpgsql;
```

実行

```text
$ psql -U scott -d city < years_ago.sql 
DROP FUNCTION
CREATE FUNCTION
```

## ストアードファンクションの実行

```sql:list.sql
SELECT name, year, years_ago(year) FROM host_cities;
```

実行

```text
$ psql -U scott -d city < list.sql 
      name      | year | years_ago 
----------------+------+-----------
 東京           | 1964 |        58
 メキシコシティ | 1968 |        54
 ミュンヘン     | 1972 |        50
 モントリオール | 1976 |        46
 モスクワ       | 1980 |        42
 ロサンゼルス   | 1984 |        38
 ソウル         | 1988 |        34
 バルセロナ     | 1992 |        30
 アトランタ     | 1996 |        26
 シドニー       | 2000 |        22
(10 行)
```

## 確認したバージョン

```text
PostgreSQL 14.5 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 12.1.1 20220730, 64-bit
```
ngrokの使い方（windows版）

## 【ngrokとは】

localhostで動いているシステムを、
公開サーバ上のようにアクセスできるツールです。

今回はローカル上のlaravel Socialite でlineログインをするために、
LINE Developpersの「コールバックURI指定」でlocalhostが使用出来ないために
解決策を探していたらこのツールの存在を知りました。


## 【環境】

・Windows11 pro
・laravel ^8.75
・laravel/socialite　: ^5.0
・socialiteproviders/line　: ^2.1



## 【前提条件】
・ngrokにアカウント登録済
・(Windows版)をダウンロードし　ngrok.zipを任意のフォルダに解凍済
・localhostでlaravel起動済


## 【使い方】

https://dashboard.ngrok.com/get-started/setup

にアクセス

![Setup - ngrok — Mozilla Firefox 2022-08-22 13.34.5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669259/287b69e7-a379-3e8a-9f2c-379a31347be8.png)



ダウンロードしたngrokのフォルダを開き、ngrok.exe　をダブルクリック
![ngrok-v3-stable-windows-amd64 2022-08-22 15.18.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669259/7cb70e56-ac06-b621-24fa-fc8d0484d48d.png)

ngrokのコマンドウィンドウが起動
![C__Users_user_Documents_app_ngrok-v3-stable-window.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669259/225f727a-f421-5f39-204e-cf1ef5cfb5d5.png)


https://dashboard.ngrok.com/get-started/setup
で下記をコピーして、ngrokのコマンドウィンドウにペースト

```
ngrok config add-authtoken xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

ポートの方も同様にコピーして
ローカルで起動しているポート番号に合わせてペースト

```
ngrok http 8080
```

すると下記のような画面になり
赤枠部分のURLをコピーしてブラウザに貼り付け

![C__Users_user_Documents_app_ngrok-v3-stable-window.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669259/02d78b57-6916-69e5-f4db-b6f2bd3bbd57.png)


Visit Site　ボタンを押下

![ERR_NGROK_6024 - You are about to visit 6d75-122-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669259/660f934c-bb92-1e52-c34d-4cc64f0db051.png)

無事localhostのlaravelの画面が表示されました

![Laravel - Google Chrome 2022-08-22 15.32.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669259/7e478ca6-2ac5-e2e9-b5e0-852806207e4b.png)



## 【参考】

https://teratail.com/questions/285618

https://biz.addisteria.com/laravel_line_integration/

https://qiita.com/Esfahan/items/74e71edfe17d9935d47e
オリジナルアプリ作成進捗

現在、プログラミングスクールで作成しているオリジナルアプリですが、
あと少しのところまで来ています。

# 問題点や困っていること
スクレイピングを使っているのですが、スクレイピングでとってきたデータの配列で配列が空かどうかで条件分岐するコードを書こうとしているのですが、そこで詰まっています。

スクールの先生にはcount()を使ったほうがいいと言われたのですが、果たして・・・

## 処理の流れ
はじめに何をしようとしているかを説明します。
①プロ野球サイトの月間スケジュール（該当チーム）をクローリングして1日ごとの試合ページのリンクを取得
↓
②1日ごとの試合ページ（結果ページ）をクローリングして、選手の成績ページのリンクを取得
↓
③成績ページから該当チームの選手の成績を取得 ※ここが問題
成績ページには両チームの成績が表示されていて、ホームかアウェイで成績の表示が異なる。

ホームは下半分、アウェイは上半分。→アウェイの場合は上からクローリングすればいいが、ホームの場合はどうやってクローリングさせるか
ここで配列が空かどうかの判定条件が必要になります。

# 完成させたい
プログラミングスクールを1か月延長して完成させることにしたので、何としても完成させたいです。

現段階のコード
https://github.com/kazunarigit/baystarsapp
固定グローバルIPアドレスを付与

# Elastic IPアドレスとは
**Elastic IPアドレス**はAWSが提供する静的なグローバルIPv4アドレス。
EC2のインスタンスは、**停止して起動し直すとグローバルIPアドレスが変わってしまう**。これではサーバーとして使用できないので、**固定のIPアドレスをインスタンスに結びつける必要がある**。この時に使用するのが、**Elastic IPアドレス**。
# Elastic IPアドレスの確保と結び付け
**Elastic IPアドレスは、AWSアカウントに結び付けられる**
要は、インスタンス単位でないので、IPアドレスを割り当てたインスタンスを削除しても確保したIPアドレスはそのままAWSアカウントが持ち続けられる。
確保したIPアドレスは別のインスタンスやネットワークに結びつけ直すことができる

また、インスタンスに最初に割り当てられるグローバルIPアドレス（起動のたびに変化するIPアドレス）は、Elastic IPアドレスを割り当てると、AWSのパブリックIPv4アドレスのプール（インスタンスに割り当てるために確保されているIPアドレス）に戻される。
割り当て済みのIPアドレスをElastic IPアドレスとして使用することもできない。
Elastic IPアドレスはリージョンごとのものなので、別リージョンで確保したElastic IPアドレスは使用できない。
# Elastic IPアドレスの料金
**確保しているだけでインスタンスやネットワークに結びつけていない場合や**、**結び付けていてもインスタンスが停止している場合なども料金がかかる**
そのため、使わないIPアドレスはプールに戻しておく方がいい。
Accessで長いテキストにインデックス設定した場合のSELECTに注意

:::note warn
今後のAccessのアップデートで挙動が変わるかもしれません。
ここに書いた内容と同じ挙動になるかどうか、使う環境（バージョン）で動作確認した方がよいです。
:::

# WHERE カラム名 = '※' の※が250文字以上だと検索結果0レコード

例えば下記のようなテーブルで…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/cbd264de-51dd-b915-ad98-fb2c2c3d0bc3.png)

テーブル作成直後に、249文字のレコードと、250文字のレコードをインサート。

```sql
INSERT INTO tester ( long_str )
VALUES ('249文字だよあああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああ0');

INSERT INTO tester ( long_str )
VALUES ('250文字だよああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああ0');
```

**249文字** に対する下記SQLは検索結果1レコード。

```sql:インサートした値と全く同じ値で検索
SELECT * 
FROM tester
WHERE long_str = '249文字だよあああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああ0';
```

しかし、 **250文字** に対する下記SQLは検索結果 **0** レコード。
**インデックス=いいえ** にすると検索結果 **1** レコード。
（インデックスを設定するかどうかで挙動が変わる）

```sql:インサートした値と全く同じ値で検索
SELECT * 
FROM tester
WHERE long_str = '250文字だよああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああ0';
```

なぜか下記ように=をLIKE変えると検索結果 **1** レコード…。

```sql:インサートした値と全く同じ値で検索
SELECT * 
FROM tester
WHERE long_str LIKE '250文字だよああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああ0';
```

## まとめ

長いテキストにインデックスを設定した時は、WHEREのイコール検索の挙動が変わるので注意。

# バージョン

Windows 10 Pro 21H2 OSビルド 19044.1889
Microsoft Access for Microsoft 365 MSO (バージョン 2207 ビルド 16.0.15427.20166) 32 ビット