OmniAICreator/Qiita-1.07M huggingface dataset:
WordPressでアニクラDJ用のアーティストサイトつくってみた。その１【サーバ選定から環境構築まで】

## 作ろうと思ったきっかけ
- アニクラ（アニクラと呼ばれるアニメ音楽が流れるDJイベント）DJやコスプレイヤーの紹介媒体は、割とチープなつくりに見えるものが多い。
- Twitterやインスタグラム、TikTokなどそれぞれの媒体で独立したアカウントを運営していることが多い印象。
- 自分のことを一つのWebサイトで効率的にＰＲできたら、活動の幅が広がるのではないかという思いが強くなった。
- 自分自身のポートフォリオ的な意味でも作成したいと思った。

## 参考図書
- [いちばんやさしい WordPress 入門教室](https://www.amazon.co.jp/%E3%81%84%E3%81%A1%E3%81%B0%E3%82%93%E3%82%84%E3%81%95%E3%81%97%E3%81%84-WordPress-%E5%85%A5%E9%96%80%E6%95%99%E5%AE%A4-%E4%BD%90%E3%80%85%E6%9C%A8-%E6%81%B5/dp/4800712653/ref=sr_1_1?crid=1U0TWDJNFOYKF&keywords=%E3%81%84%E3%81%A1%E3%81%B0%E3%82%93%E3%82%84%E3%81%95%E3%81%97%E3%81%84+wordpress+%E5%85%A5%E9%96%80%E6%95%99%E5%AE%A4&qid=1652832588&sprefix=itibannyasasii+word%2Caps%2C197&sr=8-1)
- [1冊ですべて身につくWordPress入門講座](https://www.amazon.co.jp/gp/product/B09RSRZMLJ/ref=ppx_yo_dt_b_d_asin_title_o00?ie=UTF8&psc=1)

## レンタルサーバ OR クラウドサーバ
- 今回はじめてサーバを立ててサイトを作るという観点から、なるべく簡単な環境にすることにした。
- AWSやGCP、Azureなどのクラウドを使って実装できたらかっこいいと思ったが、今回は断念。

### お金の観点
サーバを使うときに頭に入れておかないといけない観点
- レンタルサーバ
    - 機能は、ごく普通だが、定額。わりと、みえやすい。
- クラウドサーバ
    - 多機能ではあるが、きちんと設計しないとクラウド破産をするかもしれない。怖い。

### WordPressが動作するレンタルサーバを選ぶ条件
- php バージョン 7.4以上
- MySQL バージョン 5.6以上
WordPressは、上記の環境で動作することを前提としているため、必ず確認する必要がある。

### レンタルサーバの選び方
費用の他に、いくつかのポイントがある。
- WordPressを簡単にインストールできる機能があるか。
本来は、レンタルサーバに自分でインストールしなければならない。最近のレンタルサーバでは、管理画面上からインストールできる。
- サポート体制が充実しているか。
メール、電話、チャットなどで困ったときにサポートしてもらえるか。使うかどうかはわからないが、電話サポートがあった方が安心と思えた。
- 自動バックアップ機能があるか
サーバー不具合の際、データのバックアップをとってくれるか。そこまで有用に感じてはいないが、運用始めると地味に響いてきそうなポイント。
- 無料の独自SSLが提供されているか
https:// から始まる安心のURLといったイメージ。標準で対応しているレンタルサーバが多いが、念の為確認。

### WordPressを簡単にインストールできる低価格帯のレンタルサーバ
- ロリポップ！

https://lolipop.jp/

コスパ良さそう。小さく始めるなら、使い勝手良さそう。

- スターサーバー

https://www.star.ne.jp/

小さく始めるなら良さげ？

- さくらのレンタルサーバ

https://rs.sakura.ad.jp/

割と有名なイメージ。電話サポート無料なのが嬉しい。
途中から、プラン変更が結構大変なので、小さく使うなら良さげ。

- ヘテムル

https://heteml.jp/

公式サイトだと、高速とうたっている。

- エックスサーバー

https://www.xserver.ne.jp/

電話サポート付き。プラン変更柔軟ではありそう。

### Xserverさんに決定
- 正直、どのレンタルサーバも基本的にできることはほぼ変わらない。サポート体制のことを考えて、選んだ。

### WordPressインストールまで
- 独自ドメインの取得
レンタルサーバの管理画面上から、設定できる。取得が比較的容易な`.com`を使用。
- WordPressインストール完了
![スクリーンショット 2022-05-18 10.20.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1115918/8249c1f0-ea63-ac30-9835-552186ce3115.png)
無事に最初のページが表示された。

### 今後の作業予定
- サイトマップと固定ページの作成
- ロゴマークの作成
- 写真の加工
IBM Cloud CLI をProxy経由で利用する

インターネットに直接接続していない環境からProxy経由でIBM Cloud CLIを利用する場合の設定方法を紹介します。

LinuxおよびWindows 10についてはProxy用の環境変数を変更することで、ログイン認証およびコマンド実行がProxy経由で可能でした。


# Linux

Linux環境変数の設定方法（認証が不要な場合）

```
export https_proxy=http://<proxy_host>:<proxy_port>
export http_proxy=http://<proxy_host>:<proxy_port>
```

設定確認方法
```
printenv https_proxy
printenv http_proxy
```


# Windows 10

Windows用インストーラーを用いた場合、PowershellもしくはコマンドプロンプトでIBM Cloud CLIが利用できるようになります。

## 一時的にProxy経由で通信する場合

下記コマンドを実行する

```
set https_proxy=http://<proxy_host>:<proxy_port>
set http_proxy=http://<proxy_host>:<proxy_port>
```

## 恒久的にproxy経由で通信する場合

環境変数を変更してWindowsを再起動する

コントロールパネル > システム > システムの詳細設定 > 詳細設定タブ > 環境変数 > システム環境変数

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329464/b97448a4-0ba1-763c-ff4a-a371ac288856.png)


## 「コンピューターのプロキシ設定」を利用した場合


Microsoft Edge や Chrome のブラウザのProxy設定を行う際には「コンピューターのプロキシ設定」を利用しますが、「コンピューターのプロキシ設定」を行ったとしてもPowershellもしくはコマンドプロンプトの通信はProxy経由となりませんでした。

スタート > 設定 > プロキシ > 手動プロキシ セットアップ
(edge://settings/system > システムとパフォーマンス > コンピューターのプロキシ設定を開く)

|<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329464/68d64af1-4e02-8071-2e3f-d84f8ca8f313.png">|
|:--|


# 参考URL

これからIBM Cloud CLIをインストールする方へ
https://qiita.com/ayatokura/items/013bdc614a1fa30a0cc0

Windows10のプロキシ（Proxy）設定を完全削除する為の設定箇所一覧
https://qiita.com/hiren/items/01a26d5a47ff13d623fa
.exsファイル作るところから！ Elixirでの"Hello, World!"

こんにちは！
プログラミング未経験文系出身、Elixirの国に迷い込んだ？！見習いアルケミストのaliceと申します。
今回はElixirでの"Hello, World!"について、そういえば.ex/.exsファイル作るところからは誰も書いていない？！と思い、備忘録としてまとめておきます。

# Elixirでの"Hello, World!"
プログラミングの最初の一歩、言語が実行できる環境を整えて"Hello, World!"ですが、こう書いてある記事はたくさんあります。
```elixir:hello.exs
#「テキストエディタでhello.exsを作成し」以下を書き込みましょう。
IO.puts("Hello,World!")
```

ですが、私がつまづいたのはまさかのその手前！
テキストエディタか、VSCodeでも何でもいいのですが、とにかく.ex(または.exs)ファイルの作り方から分からない！[^2]となってしまいました。




## 実行環境
<dl>
  <dd>・Windows 11 Home(バージョン 21H2, OS ビルド 22000.1098)</dd>
  <dd>・Ubuntu v18.04 ※WSL2環境下</dd>
  <dd>・Elixir v1.13.4 (compiled with Erlang/OTP 25) ※WSL2環境下</dd>
</dl>



## インストール（参考記事紹介）
インストールは以下の記事を参考にさせていただきました。
ここでは詰まりませんでしたので、この記事を参考にすればElixirのインストールはまず大丈夫だと思います。

https://qiita.com/piacerex/items/6714e1440e3f25fb46a1


## .ex/.exsの違い
.ex ファイルは作成後に
```
$ elixirc <ファイル名>.ex
```
でコンパイルが必要なので最初は.exsファイルで"Hello, World!"を作るといいと思います。
（.exファイルの存在する意図としては[公式ドキュメントに書いてあります](http://elixir-lang.org/getting-started/modules-and-functions.html)）[^3]

※.exファイルでの"Hello, World!"の作り方はこちらから([『.exファイルも作るところから！ Elixirでの"Hello, World!"-その2』](https://qiita.com/Alicesky2127/items/386a669794f8be74a219))


# パターン1　 テキストエディタから.exsファイルの作成
※以下コマンドはエディタとOSにより異なります。
コマンドプロンプトを開く
→ファイルを作成したいディレクトリまでcdコマンドで移動

```
$ nano hello.exs
```
で、テキストエディタが開きます。

その中に、
```elixir:hello.exs
IO.puts("Hello,World!")
```
と書いて保存し(Ctrl+S)、閉じます。（CTRL+X)

コマンドプロンプトに戻り、hello.exsのあるディレクトリで、
```
$ elixir hello.exs #このコマンドを実行する
Hello,World! 　　  #Hello,World!が返ってくる
```


# パターン2　 VSCodeから.exsファイルの作成
※以下コマンドはエディタとOSにより異なります。
コマンドプロンプトを開く
→ファイルを作成したいディレクトリまでcdコマンドで移動
```
$ code hello.exs
```

で、VSCodeが開きます。

その中に、
```elixir:hello.exs
IO.puts("Hello,World!")
```
と書いて保存し(Ctrl+S)、閉じます。（Alt+F4)

コマンドプロンプトに戻り、hello.exsのあるディレクトリで、
```
$ elixir hello.exs #このコマンドを実行する
Hello,World! 　　  #Hello,World!が返ってくる
```



<br>

# ～Elixirの国のご案内～
※Elixirって何ぞや？と思ったらこちらもどぞ。未来がぎゅっと詰まった、Elixirは今年で生まれて10周年です:laughing::sparkles::sparkles:

https://qiita.com/piacerex/items/7bf8f9f4f5f576e597f5



[We Are The Alchemists, my friends!:bouquet:](https://qiita.com/torifukukaiou/items/6bcd5bbb80df9e594e9e "Awesome-san's Awesome article")[^1]
Elixirコミュニティは本当に優しくて温かい人たちばかり！
私が挫折せずにいられるのもこの恵まれた環境のおかげです。


まずは気軽に話しかけてみてください。[^10]


https://speakerdeck.com/elijo/elixirkomiyunitei-falsebu-kifang-guo-nei-onrainbian




[^1]: @torifukukaiouさんのAwesomeな名言をお借りしました。Elixirコミュニティを一言で表すと、これに尽きます。
[^2]: この時点での私はほぼGUIしか触れていませんので、「テキストエディタでhello.exsを作成し」と言われても「テキストエディタで編集したものは.txtにしかならないよ？？」という詰まり方をしていました...
[^3]: Elixir treats both files exactly the same way, the only difference is in intention. .ex files are meant to be compiled while .exs files are used for scripting. 
[^10]: @kn339264さんの素敵なスライドをお借りしました。Elixirコミュニティはいろんな形で活動中！
GoogleColabでクラウドストレージのwasabiを使う方法(boto3)

S3互換で安いクラウドストレージサービスのwasabiをGoogleColabと連携して使いたいと思ったので自分用にメモしておきます。

1.認証
2.ファイルの一覧取得
3.ダウンロード
4.アップロード
5.バケット作成
を記載しておきます。

```
# 必要なライブラリのインストール
!pip install boto3 -q
import boto3

# 認証情報
aws_access_key_id = アクセスキー
aws_secret_access_key = シークレットキー
region = リージョン # リージョン一覧 → https://wasabi.com/locations/
bucket = バケット名

# S3アクセス準備
s3 = boto3.resource('s3',
                       endpoint_url=f"https://s3.{region}.wasabisys.com",
                       aws_access_key_id=aws_access_key_id,
                       aws_secret_access_key=aws_secret_access_key
                   )

# 使うバケットを設定
bucket=s3.Bucket(bucket)

# file一覧の取得
files=[obj_summary.key for obj_summary in bucket.objects.all()]

# ファイルのダウンロード
bucket.download_file(ソース, ダウンロード先)

# ファイルのアップロード
bucket.upload_file(ソース, アップロード先)

#バケットの作成
#　管理画面では『_』は禁止っぽいので使わない方が良いかも？
bucket_name = 新バケット名
s3.create_bucket(Bucket=bucket_name)


```
C＃VB.NET　WordをHTMLに変換する方法

Word文書をWebに掲載する場合は、Webページからアクセスできるようにするために文書をHTMLに変換することをお勧めします。この記事では、Spire.Doc for .NETを使用して、C＃およびVB.NETでプログラムによってWordをHTMLに変換する方法を示します。

## Spire.Doc for.NETをインストールします

まず、Spire.Doc for.NETパッケージに含まれているDLLファイルを.NETプロジェクトの参照として追加する必要があります。DLLファイルは、[このリンク](https://jp.e-iceblue.com/download/spire-doc-for-net.html)からダウンロードするか、[NuGet](https://www.nuget.org/packages/Spire.Doc/)を介してインストールできます。

PM> Install-Package Spire.Doc

## WordをHTMLに変換する

次の手順は、Spire.Docfor.NETを使用してWordをHTMLに変換する方法を示しています。

**Document**インスタンスを作成します。
**Document.LoadFromFile()** メソッドを使用してWordサンプルドキュメントをロードします。
**Document.SaveToFile()** メソッドを使用して、ドキュメントをHTMLファイルとして保存します。

**C#**
```
using Spire.Doc;

namespace WordToHTML
{
    class Program
    {
        static void Main(string[] args)
        {
            //ドキュメントインスタンスを作成する
            Document mydoc = new Document();
            //Wordサンプルドキュメントを読み込む
            mydoc.LoadFromFile(@"sample.docx", FileFormat.Xml);
            //HTMLに保存する
            mydoc.SaveToFile("output_WordToHTML.html", FileFormat.Html);
        }
    }
}
```
**VB.NET**
```
Imports Spire.Doc
 
Namespace WordToHTML
    Class Program
        Shared  Sub Main(ByVal args() As String)
            'ドキュメントインスタンスを作成する
            Document mydoc  =  New Document()
            'Wordサンプルドキュメントを読み込む
            mydoc.LoadFromFile("sample.docx", FileFormat.Xml)
            'HTMLに保存する
            mydoc.SaveToFile("output_WordToHTML.html", FileFormat.Html)
        End Sub
    End Class
End Namespace
```
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/fcb6b954-5f53-0006-dcbe-69aea924aac3.png)


### 一時ライセンスを申請する

結果ドキュメントから評価メッセージを削除する場合、または機能制限を取り除く場合は、30日間有効な一時ライセンスについて[営業担当者](mailto:sales@e-iceblue.com)にお問い合わせください。
C# "1.23E-1"のような指数表示文字列を任意の数値型に変換する方法

PCから外部の装置にコマンドで値を問い合わせたら指数表示でしかも文字列でかえってくることはよくあると思います。
その文字列からdouble型やint型の任意の型へと変換するメモです。

```double型に変換.cs

string st = "1.23E-1";
double dec;

NumberStyles ns = NumberStyles.AllowExponent | NumberStyles.Float;
IFormatProvider fmt = CultureInfo.InvariantCulture;

//int.TryParseやdecimal.TryParseに変えることで任意の型へ変換可能
double.TryParse(st, ns, fmt, out dec);

MessageBox.Show(dec.ToString());
//→　0.123

```
freee APIをSalesforceで使う時のエラー　IdがIntegerの範囲を超えている


久しぶりにApexからコールアウトするとエラーになる。

For input string: "3280501675" at [line:1, column:245]

もしかしてフィールドでも変化したのかな？って散々見直したけど分かりません。

しかし、良く見るとIdってIntegerで定義してましたが... 超えている？

SalesforceのIntegerは最大　2147483647だったような...

これらの定義が問題かな。

```
    //取引関係
    public class details {
        public Integer id;
        public Integer account_item_id;               
		public Integer tax_code;        
        public Integer item_id;
        public Integer section_id;        
        public Integer[] tag_ids;
        public Integer amount;
        public Integer vat;             //消費税額
        public String description;  
        public String entry_side;       //貸借（貸方: credit, 借方: debit） 
```

無事データを取得できました。

あっれ、金額は税込だったっけ？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/30a24b98-8214-d879-f3ae-0efc7c337d52.png)

[税抜経理の設定でも税込金額で入力するの？](https://support.freee.co.jp/hc/ja/articles/360000640143-%E7%A8%8E%E6%8A%9C%E7%B5%8C%E7%90%86%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%81%A7%E3%82%82%E7%A8%8E%E8%BE%BC%E9%87%91%E9%A1%8D%E3%81%A7%E5%85%A5%E5%8A%9B%E3%81%99%E3%82%8B%E3%81%AE-)

はい、税込金額で入力します。

消費税の経理処理方法が違っても取引の登録方法は同じで、税込金額で登録します。

仕訳データは、それぞれの設定(税抜/税込)に応じて作成されます。

税抜経理処理の場合でも税込金額を入力するのは、会計ソフトとしては一般的な仕様です。
【Python】cp932 の 大容量ファイルをイイカンジに取り込みたい


# cp932 の 大容量ファイルをイイカンジに取り込みたい

## 動作環境

- Windows10 21H2
    - メモリ4GB
- Python3.9

## 大容量ってどこまで？

1GBくらいまでならいけました。
なお、CSVをインポートしたSQLite3 も1GBくらいになりましたが
問題なく接続できました。

## ソースコード

```python

import codecs
import pandas as pd
import sqlite3 as sq
import datetime

def db_migration(file_path,db_file_path):
  try:
    dt_now = datetime.datetime.now()
    print(dt_now)
    column_names = ["column{0}".format(num) for num in range(255)]
    column_data_type = {}

    for column in column_names:
      column_data_type[column] = str
    
    # CSVを開く
    print('CSV Open')
    with codecs.open(file_path,"r","cp932","ignore") as f:
      df_csv = pd.read_csv(f,header=None,names=column_names,quoting=1,converters=column_data_type)

    # CSV <-> SQLite3
    print('SQLite Open')
    conn = sq.connect(db_file_path)
    cur = conn.cursor()
    df_csv.to_sql('sample', conn, if_exists='replace')
    conn.close()
    dt_now = datetime.datetime.now()
    print(dt_now)

  except Exception as e:
    print(str(e))

```
sidekiq-scheduler で スケジュールを環境ごとに変更する

## はじめに
sidekiqを利用する際にproductionやdevelopment、stagingでそれぞれ一部実行したくないJobがでてきました
そのためスケジュールを環境ごとに変更できるようにしました

今回の記事はこちらの　issue の内容を解説したものになります

https://github.com/moove-it/sidekiq-scheduler/issues/321

### 環境ごとに別のファイルからスケジュールをロードする

READMEに記載されている内容ですが `config/sidekiq.yml` とは別のファイルでスケジュールを設定することができます

https://github.com/moove-it/sidekiq-scheduler#load-the-schedule-from-a-different-file

``` ruby
require 'sidekiq'
require 'sidekiq-scheduler'

Sidekiq.configure_server do |config|
  config.on(:startup) do
    Sidekiq.schedule = YAML.load_file(File.expand_path('../../sidekiq_scheduler.yml', __FILE__))
    SidekiqScheduler::Scheduler.instance.reload_schedule!
  end
end
```

> The above code can be placed in an initializer (in `config/initializers`) that runs every time the app starts up.

READMEより引用させていただきましたが上記の例では`config/initializers`以下に配置することでスケジュールのみを記載した`sidekiq_scheduler.yml` を用意し読み込む処理を実行することができます

``` ruby
Sidekiq.configure_server do |config|
  config.on(:startup) do
    Sidekiq.schedule = YAML.load_file(File.expand_path("config/scheduler/#{Rails.env}.yml", __FILE__))
    SidekiqScheduler::Scheduler.instance.reload_schedule!
  end
end
```

こちらの仕組みを利用してロードするファイルを環境ごとになるように`config/schedulers/development.yml`などのスケジュールファイルを用意し`Rails.env`をファイルパスに含めることで環境ごとに登録するスケジュールを変更することができます
【C#】ホスト名からIPアドレスを知りたい

# この記事は移転します

https://ymd65536.hatenablog.com/entry/2023/10/30/000546

## ホスト名からIPアドレスを調べたい

```cs
using System.Net;

//解決したいホスト名
string HostName = "ホスト名";

//IPHostEntryオブジェクトを取得
IPHostEntry iphe = Dns.GetHostEntry(HostName);

//IPアドレスのリストを取得
IPAddress[] adList = iphe.AddressList;

//IPアドレスを列挙
for (int ip_cnt = 0; ip_cnt < adList.Length; ip_cnt++)
{
  string LocalIpAddress = adList[ip_cnt].ToString();
  Console.WriteLine(LocalIpAddress);
}
```
SupabaseのDatabaseにDB Clientで接続する

最近Supabaseでプロダクトを開発することになりました。
プロトタイプを作る上でサンプルデータをSupabaseのDatabaseに入力しなくてはなりません。

僕はWindows時代に [A5:SQL Mk-2](https://a5m2.mmatsubara.com/)を重宝していたけど、残念ながらmacOS版はないみたいなので、今回はテキトーに調べて出てきた[TablePlus](https://tableplus.com)を使います。

## 用意するもの
- TablePlus - DB Clientならなんでも
- Supabaseアカウント - Project,DBは作成済み

## 手順
SupabaseのDBといっても、ただのPostgreSQLなので、一般的なDB Clientで接続できます。

1. 接続するDBの種類はPostgreSQLを選択せずに、`Import from URL`を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256853/1862c6b4-eecf-bae3-4f6f-d087ba1666dd.png)


2. SupabaseのDatabaseの `Connection string`をコピー
`Settings/Connection Pooling` にあります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256853/258f575f-3af7-8386-d4fe-ac10a3c667b1.png)

`[YOUR-PASSWORD]`をプロジェクトを作ったときのパスワードに置き換えます。
例えば、パスワードが`P@ssw0rd`なら `postgres://postgres:P@ssw0rd@db.xxxxxxxxxxxxxxxx.supabase.co:xxxx/postgres`になります。

3. 上記で作った`Connection string`で接続
こうなればOK!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256853/76f56f7e-eb23-0945-a30a-c1b230a6a046.png)
rails ページネーションの実装

### １、gem kaminariをインストール
```
gem 'kaminari'
```
としbundle installで完了。

### ２、デフォルトの設定をいじる

```
rails g kaminari:config
```
コマンドでページネーションの設定を書き込むファイルを作成。

```kaminari_config.rb
# frozen_string_literal: true

Kaminari.configure do |config|
  # config.default_per_page = 25
  # config.max_per_page = nil
  # config.window = 4
  # config.outer_window = 0
  # config.left = 0
  # config.right = 0
  # config.page_method_name = :page
  # config.param_name = :page
  # config.max_pages = nil
  # config.params_on_first_page = false
end
```
上記がデフォルトである。１ページあたりのコンテンツの数等の設定を変更できる。

##### モデルごとに設定することもできる

```user.rb
class User < ActiveRecord::Base
  paginates_per 50
end
```
モデルにpaginates_perメソッドを利用して設定する。

### ３、ページネーションのビューファイルを作成する
以下のコマンドで終結する。
```
rails g kaminari:views default
```
ページネーションのビューにbootstrapなどのフレームワークを適用させたい場合は上記コマンドのdfaultの部分を変更すれば良い。
```
rails g kaminari:views bootstrap4
```
これで完結する。

### ４、コントローラーに必要な処理を書く

```boards_controller.rb
def index
  @boards = Board.page(params[:page]).per(20).includes(:user)
end
```
pageメソッドを使うことでrailsがページネーションしてくれる。
この時にpageメソッドに必ずparams[:page]を引き渡す必要がある。
perメソッドは「２、デフォルトの設定をいじる」で行った設定に沿う場合は使う必要はない。

### ５、ビューに出力
boards_controller.erbで定義したインスタンス変数を引数に取り、ページネーションして出力してくれる。
```index.html.erb
<%= paginate @boards %>
```

以上で完成。

### 参考にしたURL
https://github.com/kaminari/kaminari#configuring-kaminari

https://pikawaka.com/rails/kaminari#%E3%83%9A%E3%83%BC%E3%82%B8%E3%83%8D%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E8%A6%8B%E3%81%9F%E7%9B%AE%E3%82%92%E5%A4%89%E3%81%88%E3%82%8B%E6%96%B9%E6%B3%95
ストレージ　IOPS  一覧 　目安

仮想マシンで特定のストレージで動作するOSの検証のためさくっとしらべようとしたら一覧が出てこなかったので作りました。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2531942/7c913b23-b0f5-7d53-342e-456178645bc7.png)
	インターフェイス	ランダムリード	ランダムライト	数値根拠	備考		
SDカード　A1クラス		1500	500	規格			
SDカード　A2クラス		4000	2000	規格			
HDD 7200rpm	SATA	75-100	-	目安			
HDD 10000rpm	SATA	125-150	-	目安			
HDD 10000rpm	SAS	140	-	目安			
HDD 15000rpm	SAS	175-210	-	目安			
SSD	SATA	95000	34000	目安		5300 PRO	
SSD	NVMe(PCIex3.0 x4)	500000	95000	目安	NVMe 1.3	7300 PRO	
SSD	NVMe(PCIex4.0 x4)	1000000	180000	目安	NVMe 1.4	7450 PRO	
SSD	NVMe(PCIex5.0 x?)	2500000	250000	目安	NVMe 1.4b?	PM1743	エンタープライズ向け
Pythonで歌詞を集めて軽く分析してみた話

これを作ろうと思った理由
---
・ただ単に歌の歌詞の頻出度が気になったから
・これを使えばなにかいい歌詞が作れるのではないか

コード
---
まずコードからお見せします。コードが雑ですが…
```python:例のコード
import requests
from bs4 import BeautifulSoup
import sentencepiece as spm
import os

net = range(1,318500)

for i in net:
    kasi = ""
    memory = ""
    load_url = "https://www.uta-net.com/song/" + str(i) + "/"
    html = requests.get(load_url)
    soup = BeautifulSoup(html.content ,"html.parser")
    for element in soup.find_all(id="kashi_area"):
        memory = element.text
    kasi += memory.replace("　", "\n").replace(" ", "\n")
    path = f"歌詞{str(i)}.txt"
    if not(os.path.isfile(path)):
        with open(path,"w",encoding="utf-8")as file:
            file.write(str(kasi))
    print(i)

count = {}
for a in net:
    path = f"歌詞{str(a)}.txt"
    if os.path.isfile(path):
        with open(path, "r", encoding="utf-8")as readfile:
            kasi = readfile.read()
        if not(kasi == "[]" or kasi == None or kasi == ""):
            TEXT = kasi
            # 学習済みモデルの読み込み
            sp = spm.SentencePieceProcessor()
            sp.load('trained_model.model')
            # 分割した結果を表示
            result = sp.EncodeAsPieces(TEXT)
            #result = "".join(result)
            print(result)
            for c in result:
                if c in count:
                    count[c] = count[c] + 1
                else:
                    count[c] = 1

new_count = {}
point = 0
for d in count:
    if count[d] <= point or str(d).isascii() or len(str(d)) <= 2:
        pass
    else:
        new_count[d] = count[d]

new_count = sorted(new_count.items(), key=lambda x:x[1])
print(new_count)

new_count = str(new_count).replace("('","").replace("',",":").replace(",","\n").replace(")","").replace("["," ").replace("]","")

with open("結果メモ.txt","w",encoding="utf-8")as file:
    file.write(new_count)
```

仕組み(?)
---
1 歌ネットから歌詞を集める
2 それをtxtファイルに保存する
3 それが終わったら、今度はファイルを読み込む
4 AIによって文章を単語単語で分けさせる
5 出てきた文字をカウントする
6 それを出力

という感じです。

今の状況報告
---
今ざっと1万近くデータが集まっています。

データが4-5千くらいのときの歌詞頻出度があるので公開します。
（3文字以上だけの語句を出しています）
順位 語句:出てきた回数
5 じゃない: 1991
4 きっと: 2007
3 なんて: 2356
2 れない: 2907
1 あなた: 5923

…こんな感じですね

また今の状況報告や、プログラムの変更があったらまた記事を書きます。
見ていただき、ありがとうございました
よく間違えて書かれるトランザクション処理について

## はじめに
自分が見てきたコードでよく間違えられて書かれるトランザクション処理をまとめました。
原因として多いのが、例外処理が正しく書けていないパターンです。

## 開発環境
- PHP 7.4.12
- CakePHP 4.2.5

## NG集
 - #### ▼ NG例 ①
```php
/** @var \Cake\Database\Connection $connection */
$connection = ConnectionManager::get('default');
try {
    // トランザクション開始
    $connection->begin();
    $this->Articles->save($saveData);
    $connection->commit();
} catch (Exception $e) {
    // キャッチされない
    $connection->rollback();
    echo $e->getMessage();
}
```
  - 〇 問題点
    - save()では例外を投げないため、Exceptionでキャッチすることができない。
 - #### ▼ NG例 ②
```php
/** @var \Cake\Database\Connection $connection */
$connection = ConnectionManager::get('default');
try {
    // トランザクション開始
    $connection->transactional(function ($connection) use ($saveData) {
        return $this->Articles->save($saveData);
    });
} catch (Exception $e) {
    // キャッチされない
    echo $e->getMessage();
}
```
  - 〇 問題点
    - ConnectionManagerのtransactionalメソッドはfalse を返したら、ロールバックを発行して false を返すため、例外をcatchできない。（※トランザクション処理自体は正しい）
    - 例外を代入する変数には何も入らない。
 
 ## OK集
 - #### ▼ OK例 ①
 
``` php
/** @var \Cake\Database\Connection $connection */
$connection = ConnectionManager::get('default');
try {
    // トランザクション開始
	$connection->begin();
	if ($this->Articles->save($saveData) === false) {
		throw new Exception('保存に失敗しました');
	}
	$connection->commit();
} catch (Exception $e) {
	$connection->rollback();
	echo $e->getMessage();
}
```

  - 〇 改善点
    - falseで判定して、例外を投げているため、Exceptionでキャッチが可能

 - #### ▼ OK例 ②

``` php
/** @var \Cake\Database\Connection $connection */
$connection = ConnectionManager::get('default');
try {
    // トランザクション開始
	$connection->transactional(function ($connection) use ($saveData) {
		$this->Articles->saveOrFail($saveData);
	});
} catch (\Cake\ORM\Exception\PersistenceFailedException $e) {
	echo $e->getMessage();
}
```

  - 〇 改善点
    - saveOrFail()により、PersistenceFailedExceptionを投げているため、再スローでキャッチが可能

## 補足
>[CakePHP4 transactionalについて](https://book.cakephp.org/4/ja/orm/database-basics.html#id13)
> このコネクションインスタンスへのインターフェースに加えて、さらに begin/commit/rollback を 簡単にハンドリングする transactional() メソッドが提供されています。
> - 引数で渡されたクロージャーを実行します。
> - もしクロージャー内で例外が発生したら、ロールバックを発行して例外を再度 throw します。
> - クロージャーが false を返したら、ロールバックを発行して false を返します。
> - クロージャーが正常終了したら、トランザクションをコミットします。

> [CakePHP4 saveOrFailについて](https://book.cakephp.org/4/ja/orm/saving-data.html#id21)
> このメソッドを使用すると、次の条件で Cake\ORM\Exception\PersistenceFailedException を投げます。
> - アプリケーションルールのチェックに失敗した場合
> - エンティティーにエラーが含まれている場合
> - 保存がコールバックによって中断された場合
Jestのまとめ --公式ドキュメントを読んで--（最低限で投稿、今後更新）

# What is Jest？
Jestは、JavaScriptのためのテスティングライブラリです。

# Jestを用いたテストの流れ
![Reactテストの流れ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2303693/849f568f-85c5-ffa0-0f13-45a83d0f0fac.png)
図1.Jestを用いたテストの流れ
## セットアップ
データベースの初期化やコンテナを表示するDOMの準備といった、テストを行う前に実行する処理を記述する。
beforeAllでは、スコープ内（トップレベルならファイル全体、describe内ならdescribe内）のテストを実行する前に1度だけ実行する処理を記述する。
beforeEachでは、スコープ内の各テストの実行前に毎回実行する処理を記述する。
※細かい実行タイミングは、[公式ドキュメント](https://jestjs.io/ja/docs/setup-teardown#%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%97)を参照

## 後始末
データベースやDOMツリーのクリーンアップといった、テストを行った後に実行する処理を記述する。
afterAllでは、スコープ内（トップレベルならファイル全体、describe内ならdescribe内）のテストが全て終了した後に1度だけ実行する処理を記述する。
afterEachでは、スコープ内の各テストを行った後に毎回実行する処理を記述する。
※細かい実行タイミングは、[公式ドキュメント](https://jestjs.io/ja/docs/setup-teardown#%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%97)を参照

## テスト
[**discribe**](https://jestjs.io/ja/docs/api#describename-fn)
複数のテストをひとまとめにするために使用する。
（多分、before・afterのメソッドのスコープを行うために使用する）

[**test**](https://jestjs.io/ja/docs/api#testname-fn-timeout)
テストの内容を記述する。
テストの内容は、javascriptの必要な処理を行た後、マッチャーを使用して実行結果を確認する。

# Jestの機能
## マッチャー
値のテストを行うためのメソッドで、expectationオブジェクトのメソッドとして定義されている。
※ 細かい使い方は、[expect API ドキュメント](https://jestjs.io/ja/docs/expect)参照

[**使用例**](https://jestjs.io/ja/docs/using-matchers)
```javascript
// 真偽値のテスト
expect(null).toBeNull();  // green
expect(true).toBeFalsy;   // red

// 数値のテスト
expect(5).toBeGreaterThan(3);  // green
expect(5).toEqual(4);          // red

// 文字列のテスト
expect('team').not.toMatch(/I/);      // greem
expect('Christoph').toMatch(/stop/);  // greem
```

## [モック関数](https://jestjs.io/ja/docs/mock-functions)（自分も完全には理解しきれていない）
以下を行うことで、コード間の繋がりをテストすることができる。
* 関数が持つ実際の実装を除去・上書きする
* 関数の呼び出し（また、呼び出しに渡されたパラメータも含め）をキャプチャする
* new によるコンストラクタ関数のインスタンス化をキャプチャする

※ 細かい使い方は、[モック関数 API ドキュメント](https://jestjs.io/ja/docs/mock-function-api)参照

**.mockプロパティ**
モック関数呼び出し時のデータや関数の返り値等が記録されている。

## [Jestオブジェクト](https://jestjs.io/ja/docs/jest-object#jestdisableautomock)
モックの作成を行ったり、Jestの全体的な動作を制御したりできる。
※ 細かい使い方は、[Jestオブジェクト API ドキュメント](https://jestjs.io/ja/docs/jest-object#jestdisableautomock)参照
AWS公式資料で挑むMLS認定(9)-Amazon PollyをPython Boto3で検証

##### [前回] [AWS公式資料で挑むMLS認定(8)-Amazon Polly音声変換の仕組み](https://qiita.com/mingchun_zhao/items/5204ddf6445e55ecc010)

## はじめに

今回はAmazon Pollyの実践編です。
AWS環境で、Python boto3を使って音声合成を行ってみます。

## AWS SDK for Python(Boto3)とは

- Pythonを使用し、AWSサービスを操作するためのライブラリ
- Pythonアプリケーション、ライブラリ、スクリプトを、AWSサービス(S3、EC2、DynamoDB)と簡単に統合可能
- 2つの異なるレベルのAPIを提供
    - クライアントAPI(低レベル)
        - 下層のHTTP API操作との1対1のマッピングが提供される
        - 例: `s3 = boto3.client('s3')`
    - リソースAPI
        - 属性にアクセスし、アクションを実行するためのリソースオブジェクトとコレクションが提供される
            - 明示的なネットワーク呼び出しは表示されない
        - 例: `s3 = boto3.resource('s3')`

## 検証環境
```
CPU: Intel(R) Core(TM) 3.30GHz(4コア8スレッド)
メモリ: 16 GB
OS: Ubuntu 20.04 LTS
```

ちなみに、Ubuntuは、Windows 10で以下のように管理者権限で導入しました。

```
> wsl --install -d Ubuntu-20.04
```

## 検証準備

### AWSのアクセスキーが必要です
※ 注意: アクセスキーはくれぐれも間違って公開しないように、厳重に保管してください。

- アクセスキー ID (access_key_id)
- シークレットアクセスキー (secret_access_key)


### boto3をインストール
```
$ pip3 install boto3
```
## 検証シナリオ

[SynthesizeSpeech Pythonコード例](https://docs.aws.amazon.com/ja_jp/polly/latest/dg/SynthesizeSpeechSamplePython.html)(英語音声)を参考に、日本語音声合成を行ってみます。
AWS SDK for Python(Boto3)を使用し、ほぼリアルタイムでテキストを音声合成できるか確認します。
アクセスキーは、実際のものに書き換えてください。
※ 再度注意: アクセスキーが含まれたソースコードをそのまま共有したり公開してはいけません!!!

```speech.py
import boto3

polly_client = boto3.Session(
    aws_access_key_id="XXXXXXXXXXXX",
    aws_secret_access_key="YYYYYYYYYY",
    region_name='ap-northeast-1').client('polly')

response = polly_client.synthesize_speech(VoiceId='Takumi',
                OutputFormat='mp3',
                Text = 'みなさん、こんにちは、これはAmazon Pollyによる音声変換のテストです。',
                Engine = 'neural')

file = open('speech.mp3', 'wb')
file.write(response['AudioStream'].read())
file.close()
```

Python実行
```
$ python3 speech.py
```

すると、カレントディレクトリに`speech.mp3`音声ファイルが生成されました。
聴いてみると、アナウンサー並みの発音で例文を読んでくれました、すごい!

楽しくなったので、[Python アプリケーション例](https://docs.aws.amazon.com/ja_jp/polly/latest/dg/examples-python.html)も試してみることに(内容は割愛)。

## おわりに

Boto3を使って、Amazon Pollyの音声合成を検証してみました。
次回は、MLサービス`Amazon SageMaker`の登場です。お楽しみに。

##### [次回] [AWS公式資料で挑むMLS認定(10)-Amazon SageMakerの基本](https://qiita.com/mingchun_zhao/items/12e1753774815168adff)
Amazon EventBridge の 使い方

Cloudwatch alertを使って、[EC2のオートリカバリ](https://qiita.com/kazwata/items/feea966dbb4b76eedc37)や、SNS -> lambdaを介してSlack通知など、便利に使っていたのですが、連携できるサービスが限られているため、EventBridgeを使ってみます。

# EventBridgeとは
EventBridgeは、AWS外のSaaSやAWSサービスで発生した様々なEventを受け取って、LambdaやStep Functions などの指定したターゲットにEventを連携することができるサーバレスのマネージドサービスです。EventBridgeという名称そのままな感じですが、Eventソースとターゲットの自由度がかなり高いので、アイデア次第で色々できそうな感があります。

# EventBridgeの設定方法
「Cloudwatch alertのイベントを受け取って、lambdaに連携する」というEventBridgeを作成してみます。まずは、Amazon EventBridge > ルール > ルールを作成、でEventBridgeのルールを作ります。EventソースにするCloudwatch alertと、ターゲットにするlambdaは作成済みとします。

:::note warn
EventソースとなるCloudwatch alertのアラーム設定には、トリガーが設定されている必要はない。あくまでAWS Eventの発生を契機にするため。
:::

## ルールタイプの設定
ルールタイプで、イベントパターンとスケジュールが選択できます。スケジュールの方は、cron的に一定間隔や指定日時でイベント駆動させるときに使えます。今回は、イベントパターンを選択します。

![スクリーンショット 2022-05-02 15.17.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989777/c125e341-1a83-8764-8ac1-ad0f19d51342.png)

:::note info
起動契機には、イベント起動とスケジュール（cron）起動が選択可能
:::

## イベントソースとイベントパターンの設定
次にイベントソースを選択します。Cloudwatch alertにしたいので、AWSイベントを選択します。
![スクリーンショット 2022-05-02 15.17.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989777/3a56bfb3-4392-c45d-71a6-7dd9cb3d594b.png)

次にイベントパターンをjsonで記述します。alarmNameには、任意のCloudWatch alarmのアラーム名を指定します。stateを指定することで、ALARM時のみイベント発行されるようにします。なお、stateを指定しなかった場合は、全てのstate changeでイベント発行されます。このjsonは拾いたいイベントのフィルタのようなイメージですね。

```json
{
  "source": ["aws.cloudwatch"],
  "detail-type": ["CloudWatch Alarm State Change"],
  "detail": {
    "alarmName": ["Event_Test"],
    "state": {
      "value": ["ALARM"]
    }
  }
}
```
このイベントパターンを書くためには、AWSサービスの各種イベントが、どんなjsonデータ構造なのかという話になります。[ここを参照すると](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-service-event.html)各種イベントのjsonサンプルがあるので参考にしながら記述すれば良いです。または、下記のサンプルイベントから、参照することができます。

![スクリーンショット 2022-05-02 16.44.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989777/77dc14d6-0bd0-d7b8-f1cd-2ebef15cc908.png)

:::note info
公開されているサンプルイベントを参考に、イベントパターン（拾いたいイベントのフィルタ）を記述する
:::

## ターゲットの設定
最後にターゲットを選択します。事前に作成しておいた、lambdaに連携しています。ターゲットは複数選択できるので、lambdaとSNSを両方指定するなども出来ます。
また、ターゲットに設定したlambdaで、連携されたjson形式のEvent情報を参照することも可能です。

![スクリーンショット 2022-05-02 16.12.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989777/c3ebac02-5d67-5df7-f4b9-f0791781a729.png)

## 作成完了
「ルールの作成」で完了。
かなり簡単に出来ますね。ルール作成した時点で、EventBridgeは有効になっています。

:::note alert
イベント駆動型なので、無限ループ（再帰呼び出し）にならないように注意
:::

## 動作確認
発行されたイベントは、Cloudwatchでメトリクス化されています。
![スクリーンショット 2022-05-02 17.02.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1989777/fc8dd4a0-cc01-575f-6e17-2c73242cfd3b.png)

ターゲットがlambdaの場合は、lambdaのログでも確認可能ですね。

## まとめ
Event Bridgeは、イベントソース、ターゲットの選択肢が多く、Cloudwatch alertより容易に出来ることのカバー範囲が広いです。単純なalert（SNS連携）ならばCloudwatchで十分、自動復旧等のためにSystem managerやStep functions、lambda等に連携するならEvent Bridgeを使う、と適材適所ですね。
Watson Assistant Tips - Web Chatをもっと大きくしたい

# できればブラウザ全体に表示したい

Web Chat機能は、その名の通り、ホームページに設置するチャットの入り口です。
通常はブラウザの右下に設置されたアイコンをクリックすると自動的にチャット・ウィンドウが開いてチャットボットに質問を入力することができます。
それを『もっと大きく』、さらには『ブラウザ全体に表示』したいという。。。
### 通常はこんな大きさ
 ![webchat1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52151/20482064-3f89-e254-8282-69afcf6a8d64.png)


# どうしてそんなに大きくしたいの？

「表示できる情報を増やしたり、ホームページの補助的な位置付けではなく、チャットボットのインターフェースそのモノとして使いたいんです」

なるほど。画面いっぱいに表示したいのであれば、こんな感じでしょうか。。。
![web2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52151/9109dd35-fd00-544b-f93d-099d73f917b2.png)

# 変更方法はこちら
画面サイズの50%程度の大きさであれば。。。
![web3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52151/80a94016-4502-990f-d625-1c5d260ce827.png)

やり方は簡単です。
Web Chatの横幅を指定することで変更可能です。
この例では、画面サイズの50%を指定しています。
```javascript
  window.watsonAssistantChatOptions = {
      integrationID: "xxx",
      region: "xxx", 
      serviceInstanceID: "xxx",
      onLoad: (instance) => {
        instance.updateCSSVariables({
            'BASE-width': '50%',
        });
        instance.render();
      }
    };
```
updateCSSVariables()を使って、Web Chat(コード上はinstanceです)のパラメータを変更します。
### ポイント箇所の抜粋
```javascript
instance.updateCSSVariables({
  'BASE-width': '50%',
});
```
横幅の他に高さも変更できるので詳細はオンラインマニュアルを参照してください。

:::note info
もっと詳しく知りたい方は、
[オンラインマニュアル](https://web-chat.global.assistant.watson.cloud.ibm.com/docs.html?to=api-instance-methods#theming)を参照してください。
:::


# いかがでしたでしょうか
また、Watson Assistantがちょっぴり好きになりました :blush:
Flutterの「謎の鳥」について紹介する

## この子の事です！！
![Dashatars (1) (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555431/50d2c8f2-33b9-7737-89e0-fabfa84c43b5.png)
## その正体に迫る
### 彼女の名前は？
**Dash**っていいます。因みに、**女の子**です！
でも、「彼」とか男性系の三人称で呼ばれることも気にしていないみたいです。
>Dash is female, but she doesn’t mind being called they, their, he, or him.

### 何者なの？
実はDashちゃん、**元々はDartのマスコットキャラクター**なのです！
> That’s right, Dash was originally a Dart mascot, not a Flutter mascot.

それがDartの開発者とFlutterの開発者の間で愛され続け。。。  
いつの間にか**DartとFlutter両方のマスコット**へと栄進！！！
> Many boxes of Dash plushies arrived in southern California just in time for the conference. They were eagerly adopted by Dart and Flutter enthusiasts.
>
> The people have spoken, so Dash is now the mascot for Flutter and Dart.

### その生態は？
実はDashちゃんは**ハチドリの仲間**です。
Dart言語のスピーディーさの象徴としてハチドリが採用されたそう。

「でも、ハチドリって角ばってて可愛くなくないか？」
「じゃあまるめちまおうぜ！」

ということで**丸められました。**
なので正確に言うと、**まるいハチドリです！**
>Early on, a hummingbird image was created for the Dart team to use for presentations and the web. The hummingbird represents that Dart is a speedy language.

> However, hummingbirds are pointed and angular and we wanted a cuddly plushy, so we chose a round hummingbird.

### Mega-Dashちゃんが存在する
今のGoogleのオフィスにはMega-Dashちゃんがお休みをしているそう。
**デカい。**
> We also have Mega-Dash, a life-sized mascot who is currently resting in a locked-down Google office.

![MegaDashChilling (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555431/ed302be7-7586-52be-3a83-5db983b6cb2c.png)


### 実はインスタグラマー
なんとDashちゃん、[**インスタ**](https://www.instagram.com/dash_the_dartlang_plushy/)をしてます！
是非フォローしてあげてください！
> Dash has an Instagram account.

### Dashちゃんに対する禁則事項！
**Dashちゃんのくちばしはまっすぐ！！曲がったくちばしで描かないで！！**
公式からのお告げです。逆らえばどうなることか、、、わかりません。
> Dash has a **straight** beak. **Please, don’t depict Dash with a curved beak.**

## 最後に
### 公式からオリジナルDashを作成するツールが公開されているので、遊んでみてね！
https://dashatar-dev.web.app/

**他にも公式サイトにはDashちゃんが生まれる工程まで細かく紹介されていますので、是非ご覧ください。**

公式：https://docs.flutter.dev/dash
引用元：https://docs.flutter.dev/dash
[Azure]でウェブサービスを構築するときの構成

今日は自分のメモ。

Azureでウェブサービスを構築するときの基本構成。パフォーマンス、コスト、メンテナンスのしやすさ（スケールアップ・ダウン）、管理するソフトウェアーコードの簡単さ等を総合的に見てどのサービスを使うか決める必要があります。

# Web App
まず、アプリケーションは Web App
- <a href="https://azure.microsoft.com/ja-jp/services/app-service/web/" target="_blank">Azure Web Appサービストップページ</a>
- <a href="https://azure.microsoft.com/ja-jp/pricing/details/app-service/windows/" target="_blank">価格ページ</a>

複数のWeb Appの上位概念としてApp Planがあります。リソースや課金はApp Plan単位で行われますので、小規模で複数のサービス開発や開発環境などは一つのApp Planにまとめておけば価格を抑えることができます。

読むといいページ
- <a href="https://www.sigmact.com/updated/zero-to-hero/part10-why-use-webapps/" target="_blank">今更聞けないAzure Web Appsを利用するメリットとは</a>

静的なウェブページをホスティングするだけならAzure StorageでOK。
- <a href="https://docs.microsoft.com/ja-jp/azure/storage/blobs/storage-blob-static-website" target="_blank">Azure Storage での静的 Web サイト ホスティング</a>

カスタムドメインを使い＋SSL証明書を紐づける場合は
- <a href="https://docs.microsoft.com/ja-jp/azure/app-service/configure-ssl-certificate?tabs=apex%2Cportal#start-certificate-order" target="_blanj">SSL証明書をAzureにて購入したい場合</a>
- <a href="https://syantien.com/en/c/software/s/azure/p/lets-encrypt" target="_blank">ちょっと手間だけど無料の証明書を使いたい場合</a>


# 画像、動画などのファイル

画像や動画などの格納は Azure Storage のBlobへ
- <a href="https://docs.microsoft.com/ja-jp/azure/storage/common/storage-introduction" target="_blank">Azure Storageドキュメント</a>
- <a href="https://docs.microsoft.com/ja-jp/azure/storage/blobs/storage-blobs-introduction" target="_blank">Azure Storage / Blob ドキュメント</a>
- <a href="https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/storage/Azure.Storage.Blobs" target="_blank">Azure Blob C#用 SDK / Github</a>

広い範囲で配信または複数からのアクセスを想定している場合はCDNを利用。
- <a href="https://azure.microsoft.com/ja-jp/services/cdn/" target="_blank">Azure Content Delivery Network サービストップページ</a>


# データベース, SQL, NoSQL, Cache

DBは基本Azure SQL、ですがAzure Storage Table, Azure Cognitive Search, Azure Cache For Redisを併用
- <a href="https://azure.microsoft.com/ja-jp/products/azure-sql/#product-overview" target="_blank">Azure SQLサービストップページ</a>
- <a href="https://docs.microsoft.com/ja-jp/azure/storage/tables/table-storage-overview" target="_blank">Azure Storage Table</a>
- <a href="https://azure.microsoft.com/ja-jp/services/search/#overview" target="_blank">Azure Cognitive Search</a>
- <a href="https://azure.microsoft.com/ja-jp/services/cache/">Azure Cache For Redis</a>

小規模の場合はとりあえずSQLにデータを投げ込んでおけばOKなのですが、DBの量が大きかったり、必ずしも全テーブルを対象として検索する必要がなかったり、逆に全文テキストを広い範囲で検索する必要な時など用途によってデータベースを変更する必要があります。

小規模複数のときはElastic Poolを利用してコストを下げることができます。詳細はこちらによくまとまっています。

- <a href="https://sqlazure.jp/b/sqlazure/2203/" target="_blank">Azure SQL DB – Elastic Database Poolについて
</a>

読むといいページ
- <a href="https://cloud.nissho-ele.co.jp/blog/sql-server_azure-sql/" target="_blank">SQL ServerとAzure SQLの違いとは？メリットとお得な移行方法を紹介</a>
PHP declare(strict_types=1)ってなんだ！？

# 概要

- PHPのコードにてファイルを作成したらnamespaseの宣言の前に呪文の様に`declare(strict_types=1);`と記載していた。詳しく意味を知りたかったのでまとめる。

# 調べてみた

- 公式ドキュメントでは下記の様に記載されている。
>declare 文は、あるコードブロックの中に 実行ディレクティブをセットするために使用します。declare の文法は他の制御構造と似ています。
- 簡単に言うとコンパイルするときの指示らしい
>ディレクティブ の箇所で、セットされた declareブロックの挙動を指定することが出来ます。 現在のところ、使用できるディレクティブは ticks ( ticksに関しては以下を参照ください)、 encoding (encoding に関しては以下を参照ください)、 strict_types (型宣言のページの 厳密な型付け も参照ください) です。
- 「strict_types (型宣言のページの 厳密な型付け も参照ください) 」と記載されているので下記のページを見てみる。
    - [厳密な型付け](https://www.php.net/manual/ja/language.types.declarations.php#language.types.declarations.strict)
- 上記を読んでみて`declare(strict_types=1)`は「strict モードを有効に設定」という意味出ることがわかった。
>デフォルトでは、PHP は誤った型の値を 可能であれば期待されたスカラー型の宣言に従うよう自動的に変換します(coercive モード)。 たとえば、関数に int が与えられたが、 引数に文字列が期待されていた場合、 文字列型の値を取得します。
ファイルごとに strict モードを有効にすることができます。 strict モードでは、型宣言に正確に対応する値のみを受け入れ、 そうでない場合、TypeError がスローされます。 このルールに関する唯一の例外は、int の値が float 型の宣言に渡せることだけです。
- strictモードはファイルごとに設定するようで、当該ファイル内から実施される関数呼び出しに適応される。
    - strictモードONのファイル から strictモードOFFのファイルの関数の呼び出し
        - 呼び出し先の関数がstrictモードONで呼び出される。
    - strictモードOFFのファイル から strictモードONのファイルの関数の呼び出し
        - 呼び出し先の関数がstrictモードOFFで呼び出される。

# じゃあstrictモードON状態ってなんや

- 下記の場合、strictモードONにしないと浮動小数点がPHPによってintに型変換されてエラーなく実行される。

```php
<?php
//declare(strict_types=1);

function sum(int $a, int $b) {
    return $a + $b;
}

//int(3)
var_dump(sum(1.5, 2.5));
```

- コメントアウトされている`declare(strict_types=1);`のコメントアウトを外し実行すると下記の様にエラーになる。

```
PHP Fatal error:  Uncaught TypeError: sum(): Argument #1 ($a) must be of type int, float given, called in /workspace/Main.php on line 8 and defined in /workspace/Main.php:4
```

- 和訳

```
PHP致命的なエラー：キャッチされないTypeError：sum（）：引数＃1（$ a）は、int型であり、floatが指定され、8行目の/workspace/Main.phpで呼び出され、/workspace/Main.php:4で定義されている必要があります。
```

# まとめ

- declare(strict_types=1);を記載するとPHPが自動で行ってくれている型変換を一切行わず、型が一致していないとエラーになるのでバグの出にくいコードが書ける！

# 情報追記

- 本内容はPHP7からの機能のようです。
    - [https://man.plustar.jp/php/migration70.new-features.html](https://man.plustar.jp/php/migration70.new-features.html)

```

```

# 参考文献

- [declare](https://www.php.net/manual/ja/control-structures.declare.php)
git pull できない「error: The following untracked working tree files would be overwritten by merge:」→できた


# git pull できない「error: The following untracked working tree files would be overwritten by merge:」→できた

# 結論（どうすればよいか）

キャッシュ的なものを消す
```git
git clean -d -f .
```
参照系が壊れたと思ったが違った？
-dオプションがいい味を出しているみたいだ・・・


```git
# 試していたこと
git pull -f
git fetch
git checkout develop -f
git checkout masuter -f
git stash
git clean
git reset --hard
```

# エラー内容
error: The following untracked working tree files would be overwritten by merge:

# 余談
最近キャッシュ系でトラブルシュート多いな・・・

もちろんリモートのブランチはちゃんと保護してから実施したほうがいいと思われる（protectしてね）

# エラー対応　参考：
https://chico-shikaku.com/2022/01/git-error-the-following-untracked/
SQLコマンドまとめ

Learn Sqlite Database With Python The Fast and Easy Way!を受けたので、そこで学んだコマンドを記事にまとめます。

## テーブルを作る

```SQL
インポートする
import sqlite3

#一時的なデータベースを作る
conn = sqlite3.connect(':memory:')

#名前のついたデータベースを作る
conn = sqlite3.connect('customer.db')

#cursorを作る
c = conn.cursor()

#テーブルを作る
c.execute("""CREATE TABLE customers (
first_name text,
last_name text,
email text
)""")

# Commit our command
conn.commit()

# Close our connection
conn.close()


```

## データをリスト形式で挿入する

```SQL
#データのリストを作成する
many_customers = [('Wes', 'Brown', 'wes@brown.com'),
 ('Steph', 'Kuewa', 'steph@kuewa.com'),
 ('Dan', 'Pas', 'dan@pas.com')]
#Insert into a database
c.executemany("INSERT INTO customers VALUES (?, ?, ?)", many_customers)

```

## クエリを書き込む

### SELECT
```SQL
c.execute("SELECT * FROM customers")
```
### fetchで抽出
```SQL
c.fetchone()
c.fetchmany(3)
items = c.fetchall()
#リストに格納することもできる
```

### fetchはリスト形式で出力されるので添字やfor文を使える
```SQL
c.fetchone()[0]

for item in items:
    print(item[0] + " " + item[1] + "\t" + item[2])
```

### 列番号をつけて出力
```SQL
c.execute("SELECT rowid, * FROM customers")
```

## WHERE
WHERE以下に条件式をつけることができる
```SQL
c.execute("SELECT * FROM customers WHERE email LIKE '%codemy.com'")
c.execute("SELECT * FROM customers WHERE age >= 20")
```

## UPDATE
```SQL
c.execute("""UPDATE customers SET first_name = 'Mary'
WHERE rowid = 4
""")
```
## DELETE(要素を削除)
```SQL
c.execute("DELETE from customers WHERE rowid = 6")
```
## ORDER BY
```SQL
c.execute("SELECT rowid, * FROM customers ORDER BY last_name DESC")
```
DESC は降順
ASCは昇順

## AND, OR
```SQL
c.execute("SELECT rowid, * FROM customers WHERE last_name LIKE 'Br%' OR rowid = 3")
```

## LIMIT
抽出する要素の個数を制限する。おそらく記述の順番が大事？
```SQL
c.execute("SELECT rowid, * FROM customers ORDER BY rowid DESC LIMIT 2")
```

## Drop Table
```SQL
c.execute("DROP TABLE customers")
```
Obsidianで日々のローカル秘蔵メモを取り込んでみたらNotionより自分好みに使えそうだった

## はじめに

自分と似たような好み (宗派) の人の参考になればと思い書いています。自分の好みとは...

- [脱ExcelしたいMarkdownテンプレート目次 - Qiita](https://qiita.com/e99h2121/items/97168cad64ff40afb77d)
- [Notion概要と、無料Markdownエディタとの比較 - Qiita](https://qiita.com/e99h2121/items/727041904ea41d02b26c#obsidian%E3%81%A8%E3%81%84%E3%81%86%E3%82%A2%E3%83%97%E3%83%AA)

ですが正直なところNotionは使いこなせているわけではなく、日々の打合せやネタ帳をただの *.txt でWindowsのお仕事自端末に保存して過ごす人生でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/e5c153a4-8fa7-ede9-0152-6f74ec98733f.png)

## きっかけ

[Obsidianは最高のマークダウン『メモ』アプリである](https://pouhon.net/obsidian-introduction/5666/)
最高とは。しかしそういえば自分の *.txt 、書くだけで見返すことができていない... 。
そこで

## WindowsデスクトップVersionを入れた

https://obsidian.md/

> Obsidian is a powerful knowledge base on top of
a local folder of plain text Markdown files.

## 扱うのは *.txt ではなく *.md 

[Obsidianは最高のマークダウン『メモ』アプリである](https://pouhon.net/obsidian-introduction/5666/)

> 扱うファイルは「.md」の拡張子を持つシンプルなマークダウンファイル

ということなので、メモ達を`ren *.txt *.md` する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/7447c7ab-6013-a36e-4410-fdf8940dacc6.png)

秘蔵メモたちが一挙にインポートできた :raised_hands: 


## カスタマイズする

### 日本語化する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/aadd5c0d-4529-2d7a-bba4-9d1455f23dd2.png)

### 外観を変える

[外観 - Obsidian 日本語ヘルプ - Obsidian Publish](https://publish.obsidian.md/help-ja/%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA/%E5%A4%96%E8%A6%B3)

デフォルトのダークからライトに変更する。これは好み。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/c572d969-5746-1b46-9c93-686253e78272.png)

### スペルチェックする

ひとまずONにしてみる。他、[マークダウンメモアプリObsidianの設定を全晒しする回](https://pouhon.net/obsidian-settings/5686/) を色々参考にした。

## 「グラフビュー」

アニメーションにしてみたらこんなことに...
![obsidian.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/a660f3eb-3d20-8cd8-d7c6-2b6d434cda53.gif)

## 検索が便利

この検索機能がとても便利だなと感じています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/21d2eb5a-d943-3cc8-e21d-d57991cb1540.png)
オプション色々。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/a6ff45b7-2b63-74a5-d4c9-3d584ddd4d97.png)


## 今時珍しいローカル型

[ローカルインストール型のObsidianがノートアプリとして最強である5つの理由 | jMatsuzaki](https://jmatsuzaki.com/archives/26813)
もともと自端末のなかにテキストファイルを貯めまくっていた自分には違和感なく、むしろ格好の環境です。Obsidian愛あふれるnote: [メモアプリObsidianマガジン｜滝林夏来｜note](https://note.com/takibayashi/m/m38cd2861c756)


## 以上

とにかく自分好みに今のところ使えているので使い続けてみます。
日々のメモなどというのは思い切りお好みによりけりと思っていますが、自分と同じ宗派の方の参考になれば嬉しいです。

追記: [MarkdownエディタObsidian v1.0.0がリリース | gihyo.jp](https://gihyo.jp/article/2022/10/obsidian)

以上です～
M1にてhomebrewをinstall後vscodeをinstallするまで

## homebrew の install
- ターミナルを起動してホームディレクトリで次のコマンドを実行
```terminal
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
> 基本的な方針の参考にさせて頂いたzennの記事
【Mac M1】VSCodeのインストール方法
(参考：[リンクはこちら](https://zenn.dev/imasaka0909/articles/deaba02e722242))

- brewコマンドが使えない
`brew -v`などのコマンドを使用すると次のようなエラーが出たのでどうやらパスを通すことでエラーの解消をすることができた。

- パスを通す
```terminal
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/ユーザ名/.zprofile
```

> パスを通す必要性とその方法に関して参考にした記事。
(参考：[記事のリンクはこちら](https://www.teamxeppet.com/macbook-m1-homebrew-install/))

## vscode の install
ここまででhomebrewが使えるようになったので、それを使ってvscodeをinstallする。コマンドは次の通りである。
```terminal
brew install visual-studio-code
```

私の場合はこれにてinstall完了である。

## 参考
https://zenn.dev/imasaka0909/articles/deaba02e722242
https://brew.sh/index_ja
https://qiita.com/___fff_/items/17655df4e80ebadd8fc3
https://chicog.me/posts/sr4qml2wg

## 経緯
- macを買い替えたが移行作業が遅かったの環境整理を始めた。
- 今まで趣味だったエンジニアだが、仕事になったので情報共有の練習も兼ねて記事を書いた。
WPFのWebBrowserコントロールでローカルPDFを開く

WPFのWebBrowserコントロールでローカルのPDFを開くとき、
日本語を含むパスの場合は、Navigate()メソッドの引数には、
String型ではなくUri型を渡す。



```c#:sample.cp
var path = @"C:\あいうお.pdf";
webBrowser.Navigate(new Uri(path));
```
~~文字コードとか考慮してURIエンコードして~~
~~String型で渡してもうまくいかなかった、、、~~
~~と思ったらちゃんと書いてありました。~~


https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.controls.webbrowser.navigate?view=windowsdesktop-6.0#system-windows-controls-webbrowser-navigate(system-uri)
【SwiftUI】LazyVGrid内の画像を正方形にする【ワークアラウンド】

## 1. はじめに
[@tsuzuki817](https://twitter.com/tsuzuki817)です🐸
SwiftUIでLazyVGrid内の画像を正方形として表示するまでに時間がかかってしまったのでシェアしておきます。

| 項番 | ページ内リンク |
|:----:|:-------------|
| 1 | [1. はじめに](#1-はじめに) |
| 2 | [2. 個々の大きさがバラバラになる](#2-個々の大きさがバラバラになる) |
| 3 | [3. アスペクト比がおかしくなる](#3-アスペクト比がおかしくなる) |
| 4 | [4. うまくいった方法](#4-うまくいった方法) |
| 5 | [5. 参考](#5-参考) |

## 2. 個々の大きさがバラバラになる
以下の方法で実装すると、大きさがバラバラになり不採用

```swift
    LazyVGrid(
        columns: Array(repeating: .init(.flexible()), count: 3),
        alignment: .center,
        spacing: 4
    ) {
        ForEach(images, id: \.self) { imageName in
            Image(imageName)
                .resizable()
                .scaleToFit() // scaleToFillでも同様
        }
    }
```
<img width="320" alt="個々の大きさがバラバラになる" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171702/ec012962-1a20-cb40-9ac3-177fa7b80b60.png">


## 3. アスペクト比がおかしくなる
以下の方法で実装すると、正方形内だけでaspectFillになってしまうので不採用

```swift
    LazyVGrid(
        columns: Array(repeating: .init(.flexible()), count: 3),
        alignment: .center,
        spacing: 4
    ) {
        ForEach(images, id: \.self) { imageName in
            Image(imageName)
                .resizable()
                .aspectRatio(1, contentMode: .fit)
        }
    }
```

<img width="320" alt="アスペクト比がおかしくなる" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171702/cecc9984-ea7d-2323-f142-78bff3af9c5d.png">

## 4. うまくいった方法
画像を任意のViewの上からoverlayすることで、scaledToFillが効き、はみ出た箇所をclippedすることで表示したい見た目にできた！採用！

```swift
LazyVGrid(
    columns: Array(repeating: .init(.flexible()), count: 3),
    alignment: .center,
    spacing: 4
) {
    ForEach(images, id: \.self) { imageName in
        Color.black
            .aspectRatio(1, contentMode: .fill)
            .overlay(
                Image(imageName)
                    .resizable()
                    .scaledToFill()
            )
            .clipped()
    }
}
```

<img width="320" alt="うまくいった方法" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171702/43358cd7-1263-b344-8745-458c1f626c8c.png">

## 5. 参考
https://stackoverflow.com/questions/64420313/how-to-make-a-lazyvgrid-of-square-images
【Docker】the input device is not a TTY解消法

## 状況
以下のように`docker compose exec`を実行したところ`the input device is not a TTY`となりました。
```:ターミナル
 $ docker compose exec <サービス名> <コマンド>
the input device is not a TTY
```

## 解消法
`docker compose exec`に`-T`を付けることで解消しました。
```:ターミナル
$ docker compose exec -T <サービス名> <コマンド>
```

`-T`オプションについて確認するために`docker compose exec --help`を実行しました。

```:ターミナル
$ docker compose exec --help

Usage:  docker compose exec [options] [-e KEY=VAL...] [--] SERVICE COMMAND [ARGS...]

Execute a command in a running container.

Options:
  -d, --detach                       Detached mode: Run command in the background.
  -e, --env stringArray              Set environment variables
      --index int                    index of the container if there are multiple instances of a service [default: 1].
                                     (default 1)
  -T, --no-TTY docker compose exec   Disable pseudo-TTY allocation. By default docker compose exec allocates a TTY.
      --privileged                   Give extended privileges to the process.
  -u, --user string                  Run the command as this user.
  -w, --workdir string               Path to workdir directory for this command.

```

`-T`を付けることによって擬似TTYの割り当てを無効にすることができるようです。
【メモ】IPアドレスとか

# IPアドレス

## グローバルIPアドレス

| クラス | IPアドレス | 用途 |
| :---: | :--- | :--- |
| A | 1.0.0.0 ～ 9.255.255.255<br>11.0.0.0 ～ 126.255.255.255 | 大規模ネットワーク |
| B | 128.0.0.0 ～ 172.15.255.255<br>172.32.0.0 ～ 191.255.255.255 | 中規模ネットワーク |
| C | 192.0.0.0 ～ 192.167.255.255<br>192.169.0.0 ～ 223.255.255.255 | 小規模ネットワーク |
| D | 224.0.0.0 ～ 239.255.255.255 | マルチキャストアドレス |
| E | 240.0.0.0 ～ 255.255.255.255 | 未割当 |

## プライベートIPアドレス

| クラス | IPアドレス | 用途 |
| :---: | :--- | :--- |
| A | 10.0.0.0 ～ 10.255.255.255 | - |
| B | 172.16.0.0 ～ 172.31.255.255 | - |
| C | 192.168.0.0 ～ 192.168.255.255 | - |

## 予約済みIPアドレス

| IPアドレス | 用途 |
| :--- | :--- |
| 224.0.0.2 | HSRPv1のHelloパケット udp/1985 |
| 224.0.0.5 | OSPFのHelloパケット |
| 224.0.0.6 | OSPFのDR/BDRルータ |
| 224.0.0.9 | RIPv2 |
| 224.0.0.18 | VRRP Advertisement |
| 224.0.0.10 | EIGRPのHelloとUPDATEパケット |
| 224.0.0.102 | HSRPv2のHelloパケット udp/1985 |
STM32 HAL FLASHとウォッチドッグの相性が悪い

# HALでFLASHとウォッチドッグタイマの相性が悪すぎる

ウォッチドッグタイマの更新の割り込みと，FLASHのeraseがカチあうとeraseが失敗して，FLASHに書き込め無くなる．
詰まっている人の助けになれば幸い．

# 対処法

FLASHのERASE中にウォッチドッグタイマの更新を行わない．
具体的にはFLASH中にタイマ割り込みをさせないわけだが，そうするとリセットかかるのでは？
私はウォッチドッグタイマを無効化した．