OmniAICreator/Qiita-1.07M huggingface dataset:
AWS11資格を効率的に制覇する受験順　by 2021 AWS Top Engineers

# 概要
『AWS11資格制覇』するための、効率的な受験順を紹介します。

このような方向け♪
・AWSの資格制覇を目指している人
・メイン業務でクラウドを使っていないが、これからクラウドを勉強したい人
・効率的にAWSの資格取得したい人

# メッセージ
メイン業務は既存SIのPM、２人の子供を育児中でしたが、
効率的に勉強し『2021 AWS Top Engineers』『AWS11資格制覇』となりました。
そしてその後１年でAWS案件を億単位で獲得できました！

少しでも、効率的に勉強をし、仕事の幅を広げたい方の参考になれば嬉しいです。

# AWSの資格って全部でなにがあるの？？
公式ページよりお借りしました。
現在、AWSの認定資格は、基礎１、アソシエイト３、プロフェッショナル２、専門５個の合計１１個あります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2608993/a6fede64-ff3c-2230-5578-2638d4e2f68b.png)

  
# 効率的な受験順は？
私が考える効率的な受験順をご紹介します。
効率的というのは、「１個前の資格の知識を生かしやすい」受験順です。
 

## ①クラウドプラクティショナー
技術者だけでなく、ユーザや営業さんでも挑戦しやすい、基礎的な試験です。
AWSを始めて勉強する方は、市販の対策本を１冊購入し、挑戦すると良いと思います。
 
## ②ソリューションアーキテクト　アソシエイト
幅広く、AWSの知識が問われます。難易度は高めですが、市販の対策本が豊富なため、勉強しやすいです。
時間とお金（会社の許可）がある方は、AWSの公式トレーニング３日間を受けることをおすすめします。（実践力も少しつきます）

 
## ③ソリューションアーキテクト　プロフェッショナル
個人的に最難関の資格です。「最難関を３番目に受けるんかい！？」と思うかもしれませんが、
幅広く、深く、知識が身につくので、ここで頑張っておくと後の試験が非常にラクです♪

実践でも非常に役に立つので、この試験で（落ちても）諦めずに踏ん張ることをおすすめします。

 

## ④SysOps
②③の知識を生かして受験することができます。また、③に比べて問題文が短くラクに受験できるかと思います。
③の合格後、一息つかずに早めに受けると、より効率的です。


## ⑤Developer
出題範囲が②③④と異なるので、新しく勉強するサービスが多いです。
ただし、④＋⑤の知識が⑥へつながるので、ここも一息つかず受験すると、⑥がラクです。
 
## ⑥DevOps　 Engineer
④＋⑤の上位資格です。③と同レベルの資格ですが、③ほど難しくありません。
最難関の③を受験後、できるだけ知識を失わずに③→④→⑤→⑥と進むと、効率的です。

 
ここまでが、基礎～アソシエイト～プロフェッショナル。ここからが専門資格になります。
 

## ⑦セキュリティ
専門資格の中では１番簡単で、市販の対策本もあり勉強しやすいです。
個人的には、①～⑥までの知識があれば、勉強しなくても合格できるかと思います。（自己責任でお願いします！）

 

## ⑧データベース
専門資格の中では２番目に簡単で、この資格も、市販の対策本があり、勉強しやすいです。

 

## ⑨ネットワーク
専門資格の中では、１番難易度が高いと噂されています。
「③ソリューションアーキテクト　プロフェッショナル」のネットワーク部分を再復習し、
Direct Connectについてしっかり学習し、受験することをおすすめします。

## ⑩データアナリティクス
⑦⑧⑨と違い、出題範囲がこれまでと非常に異なります。（一息つくならここかも）
一から勉強し直す覚悟で、出題範囲のBlack Beltやハンズオンを活用して学習することをおすすめします。

## ⑪機械学習
個人的には、専門資格の中で、１番難易度が高いと思います。AWSの知識というより、「機械学習」の知識が必要になります。

ただ⑩の知識も必要なため、⑩→⑪と時間を空けずに受験することをおすすめします。

 

 

# まとめ
以上、私が考える効率的な（１個前の資格の知識を生かしやすい）受験順でした。
最難関の「③ソリューションアーキテクト　プロフェッショナル」を乗り切った後、

（知識を忘れないように）④～⑨まで進むのがおすすめです。

 

今回は効率的な受験順に特化しましたが、他に書いてほしいネタがあれば、ぜひコメントください。
Datadog agentで取得したメトリクスの値が0になる

# つまずいたこと
datadogでsnmp監視したところ、追加したメトリクスの値が常に0となってしまっていた。
snmp監視の方法は以下を参考に構築した。
> DatadogのSNMP Integrationを利用してネットワーク機器を監視する
https://qiita.com/wuitap/items/49fe9e074fddc44d054a

# 今回参考にしたリンク
> Profile Format Reference
https://datadoghq.dev/integrations-core/tutorials/snmp/profile-format/
Metrics Types
https://docs.datadoghq.com/ja/metrics/types/?tab=count

# 原因
datadogでは、メトリクスタイプを指定することが出来る。基本的には、typeをGaugeにしておけば問題ないが追加したメトリクスはRateになっていた。
ほとんど変化しないメトリクスのため、常に0となっていた。
|type  |用途  |
|---|---|
|Gauge  |ある断面で発生した値(基本これになる)  |
|Counter  |イベント発生の合計数  |
|Rate  |前回分との差分  |

# 調査方法
debug logの取得
```
$ docker exec -it ${container_id} agent check snmp --log-level > snmp.log
$ less snmp.log
```
取得したlog
```
2022-03-30 02:04:14 UTC | CORE | TRACE | (pkg/collector/snmp/gosnmp_lib/gosnmp_log.go in Write) | logger_debug.go:13: OID:XXXXXXXXXX
2022-03-30 02:04:14 UTC | CORE | TRACE | (pkg/collector/snmp/gosnmp_lib/gosnmp_log.go in Write) | logger_debug.go:13: decodeValue: msg: value
2022-03-30 02:04:14 UTC | CORE | TRACE | (pkg/collector/snmp/gosnmp_lib/gosnmp_log.go in Write) | logger_debug.go:7: decodeValue: type is Counter64
```
debug logを見ると、上記のような形でCounter64で表示されていた。datadog内部では以下のように変換されているよう。
|SNMP type  |Inferred metric type  |
|---|---|
|Counter32  |rate  |
|Counter64  |rate  |
|Gauge32  |gauge  |
|Integer  |gauge  |
|Integer32  |gauge  |
|CounterBasedGauge64  |gauge  |
|Opaque	  |gauge  |

# 修正方法
`forced_type: XXX`の形で強制的にtypeを変更する設定を入れる。
```yaml
metrics:
    # CPU
  - MIB: CHECKPOINT-MIB
    metric_tags:
      - column:
          OID: 1.3.6.1.4.1.2620.1.6.7.5.1.1
          name: multiProcIndex
        tag: cpu_core
    symbols:
      - OID: 1.3.6.1.4.1.2620.1.6.7.5.1.2
        name: multiProcUserTime
      - OID: 1.3.6.1.4.1.2620.1.6.7.5.1.3
        name: multiProcSystemTime
      - OID: 1.3.6.1.4.1.2620.1.6.7.5.1.4
        name: multiProcIdleTime
      - OID: 1.3.6.1.4.1.2620.1.6.7.5.1.5
        name: multiProcUsage
    table:
      OID: 1.3.6.1.4.1.2620.1.6.7.5
      name: multiProcTable
  - MIB: CHECKPOINT-MIB
    symbol:
      OID: 1.3.6.1.4.1.2620.1.6.7.2.7.0
      name: procNum
    # Memory
  - MIB: CHECKPOINT-MIB
    forced_type: gauge     　　　　　　　　　　★
    symbol:
      OID: 1.3.6.1.4.1.2620.1.6.7.4.3.0
      name: memTotalReal64
  - MIB: CHECKPOINT-MIB
    forced_type: gauge　　　　　　　　　　　　　★
    symbol:
      OID: 1.3.6.1.4.1.2620.1.6.7.4.4.0
      name: memActiveReal64
  - MIB: CHECKPOINT-MIB
    forced_type: gauge　　　　　　　　　　　　　★
    symbol:
      OID: 1.3.6.1.4.1.2620.1.6.7.4.5.0
      name: memFreeReal64
```
> 詳細は公式のサンプルを確認
https://github.com/DataDog/integrations-core/blob/master/snmp/datadog_checks/snmp/data/profiles/checkpoint-firewall.yaml

# 補足
typeの指定はもっと簡単に確認することが可能だった。。。
Metrics→Summaryで確認ができる。ここからだと、メトリクスの単位(byte,kiobyte,etc)も設定出来るので便利
> Metrics Summary
https://docs.datadoghq.com/metrics/summary/
ImageJ と cellpose を使って、細胞画像の輝度値を測定する。（１）

# 目的
顕微鏡撮影した細胞画像から、細胞膜領域と細胞質基質領域の範囲を選び、その平均輝度値を求めたい！

使用するアプリケーションは、以下の通りです。
- Fiji (ImageJ)　　　　　             **←今回は、これのインストール！**
-画像解析ソフト
- Anaconda 　　　　　　
-Python を動かすところ
- cellpose
-Python で書かれた細胞画像の分節化に特化した、deep-learning に基づくアルゴリズム

上記アプリケーション（プラグインを含む）のインストールや、解析に必要なマクロを記録していきます。

### PC の環境
Windows 10

# この記事の範囲
Fiji のインストールと、画像解析に必要なプラグインのインストール方法

# Fiji のインストール

### Fiji のダウンロード
以下のリンクから、Windows 用の　"Download for Windows(64-bit)" をクリックして、ダウンロード。

[Fiji のダウンロードHP](https://fiji.sc/)

### Fiji のインストール
ダウンロードした zip ファイルを展開します。

##### 注意！
展開するときに、ファイルの保存先としては、C:\Program Files　ではなく、C:\Users\[your name]　の下に置くことを推奨されています。

"ImageJ-win64.exe" をダブルクリックすると、Fiji が起動します。


# プラグインのインストール
細胞が撮影された写真の中で、細胞の形や核の形など関心領域 (ROI) を選択して解析を行うことが多いのですが、そのROI を作成するときによく使う便利な機能をFiji に追加していきます。

後から追加する便利な機能は「プラグイン」といって、Fiji にも多数用意されています。その一つ、[MorpholibJ] を追加します。


[MorpholibJ の概要を解説しているページ](https://imagej.net/plugins/morpholibj)

### MorpholibJ のインストール
1) Fiji のメニューバーから、Help>Update... を選択します。
2) ImageJ Updater というウインドウが現れるので、左下の"Manage update sites" をクリック。
3) "IJPB-plugins" の名前を探し、左側のチェックボックスをクリックして、Close をクリック。
4) ImageJ Updater ウインドウに、"IJPB-plugins" が追加されているので、Apply changes をクリックして、インストールスタート。
5) Fiji を再起動し、メニューバーの Plugins を開くと、"MorpholibJ" が追加されています。

### Fiji へのプラグイン追加の方法
上記のMorpholibJ のように、Fiji のメニューバーからインストールできるものもあれば、Github などで公開されているプラグインや独自で開発したプラグインを手動で導入する方法もあります。

そのときに、プラグインのファイル（JARファイルなど）を格納する場所を記載します。

1) Fiji をインストールする際、zipファイルを展開したフォルダの場所を開きます。
（おそらく、C:\Users\[your name]\Fiji.app となっていると思います）
2) その中にある、"plugins" というフォルダがあるので、その中に格納します。
3) 格納されたプラグインは、Fiji のメニューバーから、Plugins の下に出てきます。

以上！
【クエリビルダ】カスタムJOINを定義してみる

ご存知のとおり [Sharperlight](https://sharperlight.jp/)は、独自のデータモデル階層を使用してデータソースと会話をしています。データモデル作成時には、対象となるデータソースに定義されているJOIN情報は、その他のスキーマ同様データモデルに取り込まれます。
しかしながら後々JOINの追加が必要なケースが発生します。通常そういった場合は、データモデルの更新で対応しますが、稼働中の本システム等では、更新には数々の監査プロセス等をこなさなくてはいけない場合が多々あります。
そのような場合、[Sharperlight](https://sharperlight.jp/)サービスを再起動するだけで済む簡易な方法が用意されています。
それがここで説明する**カスタムJOIN**です。データモデルに定義されるのではなく、独立したものとして[Sharperlight](https://sharperlight.jp/)のシステムデータベースに保存されます。では早速見ていきましょう。
先ずはクエリビルダを起動します。
**カスタムJOIN**を定義する対象となる製品とテーブルを選択します。
![2022-03-30 Figure 02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/652cbfee-9418-069f-cbfc-df0564aa0436.png)
選択領域にフィールド一覧が階層表示されます。Products\製品テーブルへのJOINが既に存在します。これは対象となるデータモデルにこのJOINが既に定義されていることを示しています。
![2022-03-30 Figure 01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/6bbf877c-0cd8-2059-d280-c3138338ba5d.png)
ここでは**カスタムJOIN**の紹介のため、同じJOINを**カスタムJOIN**として設定します。
製品Idフィールドを選択します。右クリックメニューを表示し、[カスタマイズ] -> [結合]を追加を選択します。
専用のダイアログが開くので、Join To Tableプロパティの右端にあるボタンをクリックします。
![2022-03-30 Figure 04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/a1a0e580-5c09-3141-6c81-d1c9b2d69c36.png)
結合先のテーブル、ここでは**製品**テーブルを選択し、[OK]ボタンを押します。
![5022-03-30 Figure 04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/b525aed0-76d8-e0e7-f262-3f04dee3e1f7.png)
次に、SQLJoinプロパティの右端のボタンをクリックします。
![5022-03-30 Figure 05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/42c8ec7e-c10a-3f54-73d1-7b510e93866a.png)
結合するフィールドを指定し、[Add]ボタンをクリックするとJOIN句が生成されます。[OK]を押して確定します。
![5022-03-30 Figure 06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/c864e7f0-4795-802d-609e-e3183dd2ffe8.png)
これで**カスタムJOIN**の作成は終了です。[OK]を押して保存しましょう。
作成された**カスタムJOIN**がフィールド一覧に追加されています。**カスタムJOIN**は青色で表示されます。しかし、データモデルで定義されている[製品]テーブルへのJOINと同じ説明なので間違いやすいですね。機能は同じだけどね。
**カスタムJOIN**の説明を変更してみましょう。
**カスタムJOIN**を選択し、右クリックメニューから[カスタマイズ] -> [編集]を選択します。
Descriptionプロパティを次のように変更します。
![2022-03-30 Figure 08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/d4809f5c-864f-d814-7eb9-774fe1023535.png)
[OK]を押して保存すると、フィールド一覧ではこのように識別しやすくなります。
![2022-03-30 Figure 09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/cfeed602-51ab-1a95-3f2c-88f1841da448.png)
:postbox:[Sharperlight](https://sharperlight.jp/)
【Athena】SQLで地域メッシュ（メッシュコード）から緯度経度を求める

## 地域メッシュから緯度経度を求める
[PHPでメッシュコード（最大8分の1）から中心点を取得する](https://qiita.com/YujiHamada3/items/cc7bfa9293d1c50cfed2)の記事にて地域メッシュから緯度経度をPHPスクリプトを取得したが、データベースに存在するものはSQLで計算してしまったほうが圧倒的に楽なので、SQLに置き換えることにした。緯度経度はメッシュエリアの中心点を取得している。
用意するのはmeshsテーブルでmeshというカラムに8分の1メッシュコードが入っている。

```sql
with parse_mesh AS(
    SELECT
        mesh,
        cast(substr(mesh, 1, 2) as double) as first_lat,
        cast(substr(mesh, 3, 2) as double) as first_lon,
        cast(substr(mesh, 5, 1) as double) as second_lat,
        cast(substr(mesh, 6, 1) as double) as second_lon,
        cast(substr(mesh, 7, 1) as double) as third_lat,
        cast(substr(mesh, 8, 1) as double) as third_lon,
        cast(substr(mesh, 9, 1) as double) as fourth,
        cast(substr(mesh, 10, 1) as double) as fifth,
        cast(substr(mesh, 11, 1) as double) as sixth
    FROM
        meshs
),
calculating_mesh AS(
    SELECT
        mesh,
        (first_lon + 100) * 3600 as first_lon,
        first_lat / 1.5 * 3600 as first_lat,
        second_lon * 7.5 * 60 as second_lon,
        second_lat * 5 * 60 as second_lat,
        third_lon * 45 as third_lon,
        third_lat * 30 as third_lat,
		if (fourth = 1 or fourth = 2, 0, 15) as fourth_lat,
		if (fourth = 1 or fourth = 3, 0, 22.5) as fourth_lon,
		if (fifth = 1 or fifth = 2, 0, 7.5) as fifth_lat,
		if (fifth = 1 or fifth = 3, 0, 11.25) as fifth_lon,
		if (sixth = 1 or sixth = 2, 0, 3.75) as sixth_lat,
		if (sixth = 1 or sixth = 3, 0, 5.625) as sixth_lon
    FROM
        parse_mesh
)
SELECT
    mesh as mesh_code,
    (first_lat + second_lat + third_lat + fourth_lat + fifth_lat + sixth_lat) / 3600 + (3.75 / 3600 / 2) as latitude,
    (first_lon + second_lon + third_lon + fourth_lon + fifth_lon + sixth_lon) / 3600 + (5.625 / 3600 / 2) as longitude,
FROM
    calculating_mesh
```
プログラミングスクールの講師の人（メンター）からの宿題

プログラミングスクールをする中で、メンターの人から、宿題を出されたことがあります。私が独学で勉強していたこともあり、その確認でと言うことらしいですが、PHPの文法（関数～連想配列まで）を自分が理解したことをスライドにまとめるようにとのことでした。
# 指定されたキーワードについて
指定されたキーワードは関数・引数・戻り値・変数のスコープ・配列・連想配列です。最初のメンターの人から、極力ググるなと言われていたので、PHPのドキュメントを読んでまとめたのですが、終わってみるとまとまっていなかったことが分かりました。

原因として、初心者がドキュメントオンリーでスライドにまとめるのは、難しいと言うことです。一部引用であれば良いですが、ググらないというのは混乱する原因になります。
※追記
関数（引数含む）はpaizaラーニングでもやったことがなく、ググるしか方法がありませんでした。

# 思ったこと
メンターの人の言うことは間違ってはいないですが、大事なのは **自分で考える** と言うことです。
基本ググることがメインとなる行程なので、ドキュメントに頼りすぎるのも良くないです。ドキュメントで分からないことはすぐにググったほうがいいです。

でないと、自分の言葉ではなくなってしまうので。

# 結論
初心者は初心者らしく、ググったほうがいいと言うことです。
※追記（4/5）
ドキュメントでは書き方が初心者向けではないので、ドキュメント＋ググるで違いなどをまとめたほうがいいかもしれません。
Mac で Homebrew を使わずに ImageMagick を使う

macOS で ImageMagick を使いたい場合は Homebrew で簡単に入れることができるが、ImageMagick は依存パッケージが多いのでなんとなく Homebrew で入れたくないなぁという気持ちがあり、Docker で動かしてみることにした。ちなみに Apple Silicon (M1 Mac) でも動いた。

[2022.05 追記]: FFmpeg でも同じことをやった → https://qiita.com/hoto17296/items/f9f1f22c8cde5c15da34

## 初期設定
ImageMagick が使える Docker イメージを作る。

``` Dockerfile:Dockefile
FROM debian

RUN apt-get update && apt-get -y install imagemagick
```

``` console
$ docker build -t imagemagick .
```

適当に `imagemagick` という名前でビルドしているがそこはお好きに。

## 使う
例として、作業ディレクトリ内の PNG 画像をすべて JPEG に変換してみる。

``` console
$ docker run --rm -v "$(pwd)":/mnt -w /mnt imagemagick \
    mogrify -format jpg *.png
```

注意点として、ホストの作業ディレクトリをマウントしているので、ホストの親ディレクトリのパス指定や絶対パス指定は使えない。

## エイリアスを設定する
毎回 docker コマンドのオプションを入力するのは面倒なのでエイリアスを設定して簡単に使えるようにする。

``` sh:~/.zshrc
alias imagemagick='docker run --rm -v "$(pwd)":/mnt -w /mnt imagemagick'
```

エイリアスを設定すると、先ほどの例はこのように実行できる。

``` console
$ imagemagick mogrify -format jpg *.png
```
Laravelのサービスコンテナとは

# Laravelのサービスコンテナとは

### サービスコンテナとは

DI（依存性の注入）を手助けしてくれるツール

### 主なサービスコンテナの機能

1. ****依存解決****
    
    コンストラクタで型宣言したクラスを自動でインスタンス化して渡してくれる。
    
    まじで魔法。どうなってんの。
    
2. **結合**
    
    インスタンス化方法をカスタマイズできる
    
    ```php
    app()->bind('呼び出しキーワード', 'インスタンス化方法');
    ```
    

### 結合とは

以下のように`bind`メソッドによるインスタンス化方法の記述のこと。

返す値は`interface`か実際に生成されるインスタンス（インスタンスの場合singletonでの記述をよく見る気がするので、インスタンスを返すのならそちらのほうがいいのかもしれない）

```php
app()->bind(ClassA::class, function ($app) {
    $classB = $app()->make(ClassB::class);
    return $classB;
});
```

以下のようにFacadeを使ってproxy化した形で使用することもできる。

```php
App::bind(Request::class, function ($app) {
    // Requestクラスの呼び出しをカスタマイズ
});
```

### ファサード（Facade）とは

サービスコンテナ内の基礎となるクラスへの「静的プロキシ」として機能する。

**静的プロキシとは？**

プロキシパターン（Proxy Pattern）とも呼ばれる。（逆に動的プロキシもある）

（Laravelの説明なのにGoが好きなのでなぜかGoで書いてます。すいません）

```go
type MyInterface interface {
    myMethod(string str) err;
}
type MyClass struct {
}
func (m MyClass) myMethod(string str) err {
	Println("myMethod >>>", str);
	return nil;
}
```

一般的なプロキシパターンを利用せずにMyClass構造体を呼び出した時（以下）

以下では`MyClass`オブジェクトの利用者は実際に紐付いている`myMethod`関数を使用している。

```go
myclass := &MyClass{}
Println(myclass.myMethod("not proxy patern"));
// "myMethod >>> not proxy patern"
```

### Proxy Paternで呼び出すには

同じinterfaceの実装を内部的にもたせればいい。

GoではnewがないのでNewMyproxyを実装するのと、その中で構造体に`targetObj`をもたせてそこに実際のオブジェクトをセットするようにする。

内部の`targetObj`はproxyの対象となるオブジェクトのinterface型にする。

Proxyオブジェクト経由で同じ返り値が返されるように返り値に気をつけること。

メリットとしては、本体の実装を一切変えないで機能を拡張できるというところ。

```go
type MyProxy struct {
	proxyObj MyInterface;
}
func NewMyProxy (MyInterface wrapedObj) MyProxy {
	return &MyProxy{
		proxyObj: wrapedObj,
	}
}
func (m MyProxy) myMethod(string str) err {
	Println("myProxyMethod...");
	result := m.proxyObj.myMethod(str);
	return result;
}
```

Proxyの使用を強制するような実装にすることもできる。

**Facadeの注意点**

クラスの **「スコープクリープ」**
クラスのスコープが簡単に肥大化してしまう恐れがある。ひとつのクラスを拡大することが用意であるがゆえの注意点である。

### **インターフェイスと実装の結合**

サービスコンテナの魔法機能であるタイプヒントによるインスタンスの呼び出しもとを決定できる。

以下の例は`CarInterface`を呼び出したときに、`CarClass`のインスタンスを返すというもの。

つまり、以下のような`bind`を行うことで`CarInterface`をコンストラクタの引数に取るクラスのインスタンスの自動生成ができるようになるということ。そして、その際に自動生成されるインスタンスは`CarClass`のインスタンスである。

```php
app()->bind(CarInterface::class, CarClass::class);
```

```php
class Toyota () {
	private $car;
	public function constructor(CarInterface $car){
		this->car = $car;
	}
}
```

Toyota Classを解決する際に効果を発揮する。

```php
// constructorを指定せずともCarClassのインスタンスが$toyota->$carに格納される
$toyota = app()->make(Toyota::class);
```

### 参照記事

https://qiita.com/kirisai/items/2070e29a8947e37e20b6

https://readouble.com/laravel/8.x/ja/container.html

https://qiita.com/minato-naka/items/afa4b930a2afac23261b
[tensorflow]量子化パラメータの確認

## 量子化とは

モデルのパラメータや演算結果を浮動小数点(float32など)から固定小数点(int8など)に変換することです。
モデルサイズが削減できる、組み込みデバイスなど浮動小数点演算器を持たないデバイスでも高速に推論できる、などのメリットがあります。

通常のkerasモデルはパラメータを浮動小数点型で保持しており、各レイヤーの入出力も浮動小数点型です。
```math
output(float32) = input(float32) * weight(float32) + bias(float32)
```

一方、量子化モデルではパラメータを固定小数点型で保持しており、各オペレータの入出力も固定小数点型になります。
```math
output(int8) = input(int8) * weight(int8) + bias(int32)
```

## kerasモデルのパラメータ型の確認
kerasモデルのパラメータのデータ型は以下の変数で確認できます。

```python
from keras.applications.resnet import ResNet50

model = ResNet50(include_top='False', weights='imagenet')

print("Compute dtype is {}".format(model.compute_dtype))
print("Variable dtype is {}".format(model.dtype))
```

```
Compute dtype is float32
Variable dtype is float32
```

## 量子化モデルのパラメータ型の確認
量子化モデルのパラメータのデータ型はget_tensor_detailsを使って確認できます。

```python
import tensorflow as tf

interpreter = tf.lite.Interpreter(model_path="resnet50.tflite")

tensors = interpreter.get_tensor_details()
for tensor in tensors:
    print('index:{}, name:{}, data type:{}'.format(tensor['index'], tensor['name'], tensor['dtype']))
```

```
index:0, name:serving_default_input_1:0, data type:<class 'numpy.int8'>
index:1, name:resnet50/conv1_pad/Pad/paddings, data type:<class 'numpy.int32'>
index:2, name:resnet50/pool1_pad/Pad/paddings, data type:<class 'numpy.int32'>
index:3, name:resnet50/avg_pool/Mean/reduction_indices, data type:<class 'numpy.int32'>
index:4, name:resnet50/conv1_conv/Conv2D, data type:<class 'numpy.int8'>
index:5, name:resnet50/conv1_bn/FusedBatchNormV3, data type:<class 'numpy.int32'>
…
```

tensorflow v2.8にはTensorflow Lite Model Analyzerという機能もあり、下記のように確認もできます。

```python
import tensorflow as tf

tf.lite.experimental.Analyzer.analyze(model_path="resnet50.tflite")
```

```
…
Tensors of Subgraph#0
  T#0(serving_default_input_1:0) shape_signature:[-1, 224, 224, 3], type:INT8
  T#1(resnet50/conv1_pad/Pad/paddings) shape:[4, 2], type:INT32 RO 32 bytes
  T#2(resnet50/pool1_pad/Pad/paddings) shape:[4, 2], type:INT32 RO 32 bytes
  T#3(resnet50/avg_pool/Mean/reduction_indices) shape:[2], type:INT32 RO 8 bytes
  T#4(resnet50/conv1_conv/Conv2D) shape:[64, 7, 7, 3], type:INT8 RO 9408 bytes
  T#5(resnet50/conv1_bn/FusedBatchNormV3) shape:[64], type:INT32 RO 256 bytes
…
```

## per-tensorとper-axis 

量子化モデルは各オペレータごとにscaleとzero-pointの値を持っており、元のkerasモデルの値へは以下のように変換されます。
```math
real_value(float32) = (int_value(int8) - zero_point(int32)) * scale(float32) 
```

このzero_pointとscaleの値はget_tensors_detailsで取得した値の['quantization_parameters']から確認できます。
またzero_pointとscaleはtensor毎に1つの値を持つ(per-tensor)場合と、tensorのchannel毎に1つの値を持つ(per-axis)場合とがあります。
tensorflowではoperator毎にどのように持つかが決まっており、以下のページにて確認できます。

https://www.tensorflow.org/lite/performance/quantization_spec
SSLの便利なサイト

SSLは今やごく当たり前のように使うようになりました。
以前は証明書の有効期間も、2年、3年、5年など長いものもあり、更新忘れも多くあったと記憶しています。

最近では、証明書の有効期間は1年のものが主流になり、毎年の更新がルーティーン化できるようにはなったものの、更新を忘れてしまうこともあるかと思います。

Webサイトを確認したら証明書の有効期間はわかりますが、他にどんな方法があるのかというのを書いていきたいと思います。

まず、SSLについてよく分かっていない方もいらっしゃるかと思いますので、SSL証明書について簡潔にまとまっているサイトをご紹介します。


■Joe's SSL市場　SSL証明書とは　　[https://joes-ssl.com/about/](https://joes-ssl.com/about/) 

　こちらには、SSL証明書についてから、関連することについても簡潔にまとまっているので、とてもわかりやすいです。
　


次に、現在適用されているSSL証明書の有効期限をブラウザの鍵マークから確認する以外の方法には、下記のものがあります。

■SSLサーバ証明書　導入サポートツール　　[https://sstool.cybertrust.ne.jp/support_tool/index01.php](https://sstool.cybertrust.ne.jp/support_tool/index01.php)

　こちらにFQDN（URL）を入れ、「設定を確認する」ボタンを押すと証明書の設定状況や証明書の階層の情報が詳細に表示されます。
　ここの「サーバ証明書」情報の中に有効期限も表示されます。
　※「設定確認結果」にて、証明書失効リストが取得できませんでした。と表示されることがあります。
　この場合、認証局が証明書失効リストを公開していないことになります（Let's Encrypeの証明書ではそのように表示されます。無料だからでしょうか）
　
　また、証明書の階層がわかることから、クロスルートが適用されているサイトかどうかも確認することが出来ます。
　クロスルートが適用されているサイトは携帯電話にも幅広く対応していることが多いため、対応する端末を増やすことが出来ます。


■SSL Checker　　[https://www.sslshopper.com/ssl-checker.html](https://www.sslshopper.com/ssl-checker.html)
　こちらはdigicert社が提供する確認サイトです。
　こちらは証明書の有効期限まであと何日あるかが表示されます。


次にSSLに関する便利なツールを公開しているサイトです。

■TECH-UNLIMiTED｜すぐに使える便利なWEBツール　　[https://tech-unlimited.com/](https://tech-unlimited.com/)

　こちらにはSSL以外でもいろいろなツールが登録されていますが、SSLに関しては以下の3つがあります。
　
　・CSR作成
　　　SSL証明書を作成する際に必要な情報が含まれたデータ（CSR)を作成できるものです。
　　　こちらは、Apache限定となっていますが、基本的にはApacheでもopensslなどでCSRの作成を行います。
　　　やむを得ない事情でCSRが作成できない場合は利用すると便利でしょう。
　　　なお、IISについては、IIS上から作成を行うようにしてください。
　
　・CSR内容確認
　　　上記やApache、IISにて作成したCSRの内容が入力したものと相違ないかを確認できるツールです。
　　　こちらも、Apacheであればコマンドで確認することが出来ますが、GUIでの確認が出来るため、初心者の方には便利なものとなっています。
　
　・crtファイル内容確認
　　　CSRを認証局に提出し、証明書が発行されたものをGUIにて確認することが出来ます。
　　　証明書を設置した際にエラーが表示された場合や、発行された証明書が目的のものと同じか、また新しい証明書の有効期限なども確認することが出来ます。
　　　また、同様に設置すべき中間証明書も確認することが出来ます。


■rapidsslonline　　[https://www.rapidsslonline.com/ssl-tools/ssl-converter.php](https://www.rapidsslonline.com/ssl-tools/ssl-converter.php)

　こちらには、Apacheなどopensslにて証明書の形式を変更するコマンドが掲載されています。
　・ PEM to DER
　・ PEM to P7B
　・ PEM to PFX
　・ DER to PEM
　・ P7B to PEM
　・ P7B to PFX
　・ PFX to PEM
　
SSLで調べてみたいことや証明書の形式を変換したいときなど、活用いただけるのではないかと思います。
Filebeatで特定のdocker containerのlogを取得する

# やりたいこと
様々なdocker containerが動いている環境で、指定したcontainer logのみ収集したい事例が出てきたのでそのやり方メモする。

# やり方
## 1. 使用する機能
FilbeatのAutodiscoverを使用する。Autodiscoverは、dockerやkubernetes環境下で使用することが出来る。一例として、以下のフィールド条件を指定して収集条件を設定することが出来る。
1. docker
    1. docker.container.id
    2. docker.container.image
    3. docker.container.name
    4. docker.container.labels
2. kubernetes
    1. kubernetes.labels
    2. kubernetes.annotations
    3. kubernetes.node.name
    4. kubernetes.namespace
>  詳細は公式ページを確認
https://www.elastic.co/guide/en/beats/filebeat/current/configuration-autodiscover.html

## 2. filebeat confの書き方
今回はcontainer名を条件したが、多くの方はimageとかを条件にすることが多いのかな。
```
filebeat.autodiscover:
  providers:
    - type: docker
      templates:
        - condition:
            contains:
              docker.container.name: nginx
          config:
            - type: container
              path:
                - /var/lib/docker/containers/${data.docker.container.id}/*.log
```
[Drupal]ワークフロー周りのチートシート

Content ModerationモジュールとWorkflowsモジュールで実装しているワークフロー周りのチートシートです。　

※随時追加予定

ノードが使用しているワークフロータイプのマシン名を取得する
```php
$workflow_type = \Drupal::service('entity_type.bundle.info')
   ->getBundleInfo('node')[$node->bundle()]['workflow'];
```

特定のタイプのワークフローのコンフィグエンティティを召喚する
```php
// ワークフローのコンフィグエンティティ.
$workflow = \Drupal::service('entity_type.manager')
  ->getStorage('workflow')
  ->load(WORKFLOW_TYPE);

// モデレーション状態のマシン名やラベル等の配列.
$workflow->get('type_settings')['states'];

// デフォルトのモデレーション状態.
$workflow->get('type_settings')['default_moderation_state']
```

ワークフローのコンフィグエンティティからモデレーション状態のコンフィグエンティティを召喚する
```php
// モデレーション状態のエンティティの配列を召喚する.
$moderation_states = $workflow->getTypePlugin()->getStates();

// 特定のモデレーション状態のエンティティを召喚する.
$moderation_state = $workflow->getTypePlugin()->getState('draft');

// モデレーション状態のラベルを取得する.
$moderation_state->label();

// モデレーション状態のウェイトを取得する.
$moderation_state->weight();

// モデレーション状態が公開かどうか確認する.
$moderation_state->isPublishedState();

// モデレーション状態がデフォルトリビジョンか確認する.
$moderation_state->isDefaultRevisionState();

```
ストアドプロシージャの中ではLOCK TABLESが利用できないのでネクストキーロックで代替する

# スコープ

 - MySQL / InnoDB

# 代替クエリ

テーブル全体の更新・挿入・削除をロックする場合は下記の通り。

```sql
SELECT id FROM tbl_name FOR UPDATE;
```

自動採番の挿入のみのテーブルであれば、以下でもカバー可能

```sql
SELECT id FROM tbl_name ORDER BY id DESC LIMIT 1 FOR UPDATE;
```

(※1)トランザクションの中で実行すること。よって、実際には以下のようになる。

```sql
START TRANSACTION;
SELECT id FROM tbl_name FOR UPDATE;
任意のクエリ
COMMIT; -- ここでロックが開放される
```

(※2)トランザクション分離レベルが `REPEATABLE READ` (InnoDBのデフォルト)であること。`SERIALIZABLE` の場合は、FOR UPDATEをしなくてもロックが掛かるし、 `READ COMMITTED` の場合は、上記のコマンドではロックを掛けることができない。

# 冒頭のコマンドでロックを掛けられる理由

冒頭のコマンドでは、SELECTで取得した行にしかロックが掛からず、新たな行の挿入は防げないように見えるが、そうではない。

挿入に対するロックを可能にしているのは「ネクストキーロック」というInnoDBの仕組みである。

以下では、公式リファレンスのロックに関する記述から、理由を紐解いていく。

## ネクストキーロックとは？

ネクストキーロックそのものの説明は割愛する。ネクストキーロックがわからない方は、以下を参照してください。

- 公式情報： [14.2.6 InnoDB のレコード、ギャップ、およびネクストキーロック](https://dev.mysql.com/doc/refman/5.6/ja/innodb-record-level-locks.html)
- 過去の解説記事：[[InnoDB]ネクストキーロックとは、あるいはSELECT FOR UPDATEの注意点](https://qiita.com/taumu/items/8fa668e00c8ef2ab1479)


## ネクストキーロックの掛かる条件

ネクストキーロックは以下の2条件を両方満たす場合に掛かる。

(1) 特定のステートメントを実行した場合
(2) WHERE句による絞り込みが、一意なインデックスを指定していない場合


### (1) 特定のステートメントを実行した場合

対象となるステートメントは、[14.2.8 InnoDB のさまざまな SQL ステートメントで設定されたロック](https://dev.mysql.com/doc/refman/5.6/ja/innodb-locks-set.html)に全て記載されており、`SELECT ... FOR UPDATE` のほか、 `UPDATE` や `DELETE` でもネクストキーロックが掛かる。

### (2) WHERE句による絞り込みが、一意なインデックスを指定していない場合

[14.2.6 InnoDB のレコード、ギャップ、およびネクストキーロック](https://dev.mysql.com/doc/refman/5.6/ja/innodb-record-level-locks.html)では、「一意のインデックスを使用して一意の行を検索することで行をロックするステートメントでは、ギャップロックは必要ありません。」と述べている。これは、裏返せば、一意でないクエリに対しては、ネクストキーロックが掛かることを意味する。冒頭のクエリは、一意な条件を指定していないので、ネクストキーロックが掛かる。

なお、英語版のリファレンスにはこの条件について、より明確に記載されている[[14.7.3 Locks Set by Different SQL Statements in InnoDB](https://dev.mysql.com/doc/refman/5.6/en/innodb-locks-set.html)]。


## ネクストキーロックが存在する背景

ネクストキーロックの存在理由は、 `REPEATABLE READ` では防ぐことのできないファントムリードを防ぐこと、と考えるのが良さそうである。

[14.2.7 ネクストキーロックによるファントム問題の回避](https://dev.mysql.com/doc/refman/5.6/ja/innodb-next-key-locking.html)では、『ファントムの発生を回避できるように、InnoDB では通常、インデックス行ロックとギャップロックを組み合わせたネクストキーロックと呼ばれるアルゴリズムが使用されます。』と述べられている。

ファントムリードとは、SELECTが 2回実行された場合に、1回目には返されなかった行が2回目には（他のスレッドからの挿入・削除によって）返される現象である。

冒頭のクエリはファントムリードが発生しうるクエリであり、背景からもネクストキーロックが掛かるのは自然かと思われる。
たまに使うGitコマンド集

# はじめに

便利だが、たまにしか使わないコマンドをメモとして残します。

## 基本方針

- main へのマージは squash する
  - squash するので rebase は使わない
  - squash するので feature の commit は自由にする
  - main からの merge commit も気にせず入れる

## 基本的なコマンド

https://qiita.com/shimotaroo/items/b73d896ace10894fd290

## 見つからないコマンド

### エディターをVimに変更したい

``` shell
git config --global core.editor vim
```

### リモートの状態に戻したい

``` shell
git switch feature
git fetch origin # ローカルを最新にする
git reset --hard origin/feature # 強制的に戻す 
```
[gitでリモートのブランチにローカルを強制一致させたい時](https://qiita.com/ms2sato/items/72b48c1b1923beb1e186)

### 一時的に変更を退避したい

``` shell
git stash -u # 退避する
git stash pop # 退避内容を戻して消す apply & drop
```
[【git stash】コミットはせずに変更を退避したいとき](https://qiita.com/chihiro/items/f373873d5c2dfbd03250)

### マージ先の変更を取り込む

``` shell
git switch develop
git pull origin develop # ローカルを最新にする
git switch feature 
git merge develop # developの変更をfeatureに取り込む
# コンフリクトする場合は解消する
git push
```

[pull requestでCan't automatically merge発生の場合の対応](https://qiita.com/hibriiiiidge/items/7fee5035a48dbb73aa51)

### リモートの直前のコミットを取り消したい 

``` shell
git switch feature
git reset --hard HEAD^ # 1つ前の状態に戻す
git push origin feature 
```

[困ったときの git reset コマンド集](https://qiita.com/ChaaaBooo/items/459d5417ff4cf815abce)

### リモートのコミットのコメントを修正したい

forceが利用できる環境のみ可能

``` shell
git switch feature
git rebase -i HEAD~1
# 一覧の変更したいコミットの pick を reword に変更し、保存する
git push --force origin feature
```

[GitHub Docs - 古いまたは複数のコミットメッセージの修正](https://docs.github.com/ja/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/changing-a-commit-message#amending-older-or-multiple-commit-messages)

### 空のブランチを作成したい

``` shell
git checkout --orphan doc
```

[gitの空ブランチを作る](https://qiita.com/akiko-pusu/items/7c0a99b8cb37882d2cfe)

## 参考

https://git-scm.com/book/ja/v2

- 本家

https://k.swd.cc/learnGitBranching-ja/

- 練習用サイト
WSLからssh接続した先のGUIを表示できない: vcXsrv

## 環境
* windows10
* vcxsrv
* Ubuntu20.04 on WSL2
* Raspi4 8GB RAM
* Raspi image: (64bit)v1.0.0.20220219.MiniPupper_V2_ROS&OpenCV_Ubuntu20.04.03.img.zip

## 状況
wslでラズパイにssh接続した後、vcxsrvの設定をしてxeyesを試そうとしたが表示できない。

## 解決策
export DISPLAY=\\$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0.0 を以下のように変更する
＊(windows10のipアドレス)はwindowsのコマンドプロンプトでipconfigと打って出てきた自分のipアドレス
```:~/.bashrc
export DISPLAY=(windows10のipアドレス):0.0
```

これは一時的な対策かもしれないのでご了承ください。
DatabricksにおけるPythonユーザー定義関数(UDF)

[User\-defined functions \- Python \| Databricks on AWS](https://docs.databricks.com/spark/latest/spark-sql/udf-python.html) [2021/3/17時点]の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

# UDFとして関数を登録する

```py:Python
def squared(s):
  return s * s
spark.udf.register("squaredWithPython", squared)
```

オプションとしてUDFの戻り値の型を設定することができます。デフォルトの戻り値は`StringType`となります。

```py:Python
from pyspark.sql.types import LongType
def squared_typed(s):
  return s * s
spark.udf.register("squaredWithPython", squared_typed, LongType())
```

# Spark SQLでUDFを呼び出す

```py:Python
spark.range(1, 20).createOrReplaceTempView("test")
```

```sql:SQL
%sql select id, squaredWithPython(id) as id_squared from test
```

# データフレームでUDFを使う

```py:Python
from pyspark.sql.functions import udf
from pyspark.sql.types import LongType
squared_udf = udf(squared, LongType())
df = spark.table("test")
display(df.select("id", squared_udf("id").alias("id_squared")))
```

あるいは、アノテーション構文を用いて同じUDFを宣言することができます。

```py:Python
from pyspark.sql.functions import udf
@udf("long")
def squared_udf(s):
  return s * s
df = spark.table("test")
display(df.select("id", squared_udf("id").alias("id_squared")))
```

# 評価順序とnullチェック

Spark SQL(SQL、データフレーム、データセットAPIを含む)は、サブ表現の評価順序を保証しません。特に、オペレーターや関数の入力は必ずしも左から右、あるいは固定の順序で評価されません。例えば、論理演算の`AND`や`OR`表現には、左から右の「短絡」のセマンティクスはありません。

そのため、`WHERE`や`HAVING`句のようなブール演算の評価順序はクエリー最適化やクエリー計画の間で並び替えられる可能性があるためこの順序や副作用に依存するのは危険です。特にUDFがnullチェックで短絡セマンティクスに依存している場合、以下のようにUDFを呼び出す前にnullチェックが行われることは保証されません。

```py:Python
spark.udf.register("strlen", lambda s: len(s), "int")
spark.sql("select s from test1 where s is not null and strlen(s) > 1") # no guarantee
```

この`WHERE`句はnullを除外する前に`strlen`UDFが呼び出されることを保証しません。

適切にnullチェックを行うためには、以下のいずれかを行うことをお勧めします。

- UDF自身でnullに対応するようにし、UDF内でnullチェックを行うようにします。
- nullチェックに`IF`や`CASE WHEN`表現を使用し、条件分岐でUDFを呼び出します。

```py:Python
spark.udf.register("strlen_nullsafe", lambda s: len(s) if not s is None else -1, "int")
spark.sql("select s from test1 where s is not null and strlen_nullsafe(s) > 1") // ok
spark.sql("select s from test1 where if(s is not null, strlen(s), null) > 1")   // ok
```

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
レポートを見ることができないときの対応


# 回避策

このエラーの背後にある理由は、以下に概説されているいくつかの状況（組織全体のデフォルト、フィールドレベルのセキュリティ、プロファイル、およびユーザー権限）が原因である可能性があります。 


+ レポートタイプが「デプロイ済み」ステータスになっていることを確認してください。 **Check that your Report Type is in "deployed" status.**
+ レポートフォルダにアクセスできると思われる場合でも、何らかの理由でアクセスが変更されていないことを再確認することをお勧めします。**Even though you think you have access to the Report Folder, it's a good practice to double check that the access has not changed for some reason.**
+ レポートが参照するオブジェクトの1つに「読み取り」アクセスすることはできません。**You don't have 'read' access to one of the objects that the report references.​​**
+ レポートが管理レポート（ユーザー、レポート、またはドキュメントに関するレポート）の場合は、プロファイルに「セットアップと構成の表示」権限が必要です。**​If the report is an Administrative report (reports on Users, Reports or Documents) you require the "View Setup and Configuration" permission on your profile.**
+ [ルックアップ]または[マスター/詳細関係]フィールドのフィールドレベルのセキュリティをチェックして、プロファイルにそのフィールドが表示されることを確認します。その特定のフィールドを可視化しないと、そこに含まれる関係を表示することができず、したがってレポートを実行できません。**Check the Field Level Security of the Lookup or Master-Detail Relationship field to ensure that your Profile has visibility to that field.  Without visibility into that specific field, you will not have the ability to view the relationship that it contains and thus not able to run the report.**

  注：レポートおよび参照しているオブジェクトにあるすべてのフィールドについて、フィールドレベルのセキュリティを確認する必要があります。**Note: You'll need to check the Field Level Security for every field that is on your report and in the object you are referring to.​

+ プロファイル権限「レポートビルダー」は、影響を受けるユーザーのプロファイルでは使用できません。**Profile permission "Report Builder" is not available on the affected User's Profile.**
+ レポートが複数のオブジェクトに基づいて作成されている場合、2つのオブジェクト間のルックアップフィールドがフィールドレベルのセキュリティによって非表示になっていると、このエラーが発生する可能性があります。**If the report is built on multiple objects, this error can occur if the Lookup Field between two of the Objects is hidden from you by Field Level Security.**
+ レポートの作成に使用されたレポートタイプが「商談製品」であり、影響を受けるユーザーが少なくとも「価格表」オブジェクトへの「読み取り」アクセス権を持っていない場合。**If the Report Type used to create the report is 'Opportunities with Products,' and the affected user does not have at least 'Read' access to the Price Book object.**
これと同じエラーが、カスタマーポータル/コミュニティおよびパートナーポータル/コミュニティ内のユーザーによって発生する可能性があります。これは、報告されているオブジェクトの組織全体のデフォルト共有がプライベートとして設定されていない場合に発生します。組織の残りの部分にさらにアクセスを許可する必要がある場合は、共有ルールを定義できます。**This same error may be encountered by users within Customer Portals/Communities and Partner Portals/Communities. This will occur if the Organization Wide Default sharing for the Object(s) being reported upon is not set as Private. If further access should be granted to the remainder of your Organization, Sharing Rules can be defined. ​**

  注：このエラーは、レポートタイプで使用されるオブジェクトが、visualforceページを含む管理パッケージの一部である場合にも発生する可能性があります。 **Note: This error may also occur if the object used in a report type is part of a managed package that contains a visualforce page.**

参照元:[ユーザーはレポートを見ることができません](https://developer.salesforce.com/forums/?id=906F0000000D6OdIAK)

# 関連する質問

+ レポートが別のオブジェクトに接続されていて、その人がそのオブジェクトにアクセスできないことに気付きました。
[パブリックフォルダの下のレポートへのアクセス](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000FxW0O)
レポートでRecord Typeを使う

どうもうまく使える場所とそうでない場所がある。

[Case Report Formula for Case Record Type](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000FxbhmSAB)

+ 行レベルのフィールドでは使えない
+ 集計レベルのフォールドでは使えそう

```
 If($RecordType.Name = "New Sales", Amount*0.08, Amount*0.02)
```

[行レベルの数式でレコードタイプフィールドを使用することは可能ですか？](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000A8SALSA3)
[商談レコードタイプに基づいてレポートにサマリー数式列を作成しても機能しませんか？](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000A8gOuSAJ)
Map.filter/2を楽しみます（Elixir）

**ひさかたの光のどけき春の日にしづ心なく花の散るらむ**

この歌は、私が学んだ小学校の国語の教科書に載っていました。
そらで言えます。

---

Advent Calendar 2022 83日目[^1]の記事です。
I'm looking forward to 12/25,2022 :santa::santa_tone1::santa_tone2::santa_tone3::santa_tone4::santa_tone5:
私の[Advent Calendar 2022 一覧](https://docs.google.com/spreadsheets/d/1HQvFjagQLRPjOYAjDVzWp9S4b8dKixxvvaz_TtbZWto/edit#gid=1723448955)。

[^1]: @kaizen_nagoya さんの「[「@e99h2121 アドベントカレンダーではありますまいか Advent Calendar 2020」の改訂版ではありますまいか Advent Calendar 2022 １日目　Most Breakthrough Generator](https://qiita.com/kaizen_nagoya/items/49ebebee3a0377f3b59b)」から着想を得て、模倣いたしました。 

---



# はじめに

[Elixir](https://elixir-lang.org/)を楽しんでいますか:bangbang::bangbang::bangbang:

今日は、[Map.filter/2](https://hexdocs.pm/elixir/Map.html#filter/2)を紹介します。

# 動機

[Map.filter/2](https://hexdocs.pm/elixir/Map.html#filter/2)を紹介しようとおもった動機です。

- 使用したことがない
- [Elixir](https://elixir-lang.org/) 1.13.0で追加された関数
- Advent Calendar 2022 goes behind 7 days. :sweat_smile:

# [Map.filter/2](https://hexdocs.pm/elixir/Map.html#filter/2)

公式の説明をそのまま掲載します。

![スクリーンショット 2022-03-30 8.47.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131808/d642d8f5-86c0-eca7-a057-cea8f1dd4a47.png)



サンプルを貼っておきます。

```elixir
iex> Map.filter(%{one: 1, two: 2, three: 3}, fn {_key, val} -> rem(val, 2) == 1 end)
%{one: 1, three: 3}
```

上記の例では、値が奇数である要素をMapに残すことになります。
第2引数の関数は、各要素をタプルで`{キー, 値}`を受け取ります。
関数の結果でTruthyなものを返した要素がMapに残ります。


## Truthy、Falsy

Truthy、Falsyについては、公式の[Truthy and falsy values](https://hexdocs.pm/elixir/Kernel.html#module-truthy-and-falsy-values)をご参照ください。

- `nil`と`false`がFalsyです
- 上記以外は、Truthyです

## Note

@mnishiguchi さんに重要なポイントを教えていただきました。
追記しておきます。
公式ドキュメントの`Note`です。

:::note info
if you find yourself doing multiple calls to Map.filter/2 and Map.reject/2 in a pipeline, it is likely more efficient to use Enum.map/2 and Enum.filter/2 instead and convert to a map at the end using Map.new/1.
:::

> パイプラインの中で何度もMap.filter/2やMap.reject/2をするくらいなら、そのかわりにEnum.map/2やEnum.filter/2を使って最後にMap.new/1でMapにするほうが効率的です。


# [Map.reject/2](https://hexdocs.pm/elixir/Map.html#reject/2)

[Map.filter/2](https://hexdocs.pm/elixir/Map.html#filter/2)があれば、[Map.reject/2](https://hexdocs.pm/elixir/Map.html#reject/2)もあるだろう！ :rocket: 

```elixir
iex> Map.reject(%{one: 1, two: 2, three: 3}, fn {_key, val} -> rem(val, 2) == 1 end)
%{two: 2}
```

ありました :tada::tada::tada: 

上記の例では、値が奇数ではない（つまり偶数である）要素をMapに残すことになります。
第2引数の関数は、各要素をタプルで`{キー, 値}`を受け取ります。
関数の結果でFalsyなものを返した要素がMapに残ります。

Truthy、Falsyについては、公式の[Truthy and falsy values](https://hexdocs.pm/elixir/Kernel.html#module-truthy-and-falsy-values)をご参照ください。

- `nil`と`false`がFalsyです
- 上記以外は、Truthyです


---

# Wrapping up :lgtm::lgtm::lgtm::lgtm::lgtm:

Enjoy [Elixir](https://elixir-lang.org/):bangbang::bangbang::bangbang:
<font color="purple">$\huge{Enjoy\ Elixir🚀}$</font>

本日は、以下をご紹介しました。


- [Map.filter/2](https://hexdocs.pm/elixir/Map.html#filter/2)
- [Map.reject/2](https://hexdocs.pm/elixir/Map.html#reject/2)
- [Truthy and falsy values](https://hexdocs.pm/elixir/Kernel.html#module-truthy-and-falsy-values) はご一読をオススメします



以上です。
Rails 6.1.5で uninitialized constant Mail::TestMailer というエラーが出る場合の対処法

Railsでメールを送信しようとすると以下のようなエラーが出る場合があります。

```
NameError (uninitialized constant Mail::TestMailer

      delegate :deliveries, :deliveries=, to: Mail::TestMailer
                                                  ^^^^^^^^^^^^):
  
app/mailers/application_mailer.rb:1:in `<main>'
app/mailers/user_mailer.rb:1:in `<main>'
app/controllers/home_controller.rb:3:in `index'
```

![Screen Shot 2022-03-30 at 7.41.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7465/697252ea-a3de-6e4c-c039-f9b2bae1ef1c.png)

僕が調べる限り、以下の条件が揃ったときに発生するようです。

- Rails 6.1.5を使用（これ以外のバージョンだと発生しない）
- Ruby 3.1系を使用（Ruby 3.0だと発生しない）
- メール送信を実行しようとする

## 原因と解決方法

どうやらRuby 3.1でnet-smtpが外部gemになったことに起因しているようです。

> The following default gems are now bundled gems.
> 
> - net-ftp 0.1.3
> - net-imap 0.2.2
> - net-pop 0.1.1
> - net-smtp 0.3.1
> - matrix 0.4.2
> - prime 0.1.2
> - debug 1.4.0
>
> https://github.com/ruby/ruby/blob/v3_1_0/NEWS.md

Gemfileに"net-smtp"を追加して`bundle install`＆サーバーを再起動するとこのエラーは解消します。

```ruby:Gemfile
gem 'net-smtp'
# ついでに以下の2つも追加しておく方が良さそう
gem 'net-imap'
gem 'net-pop'
```

## もう少し詳しく

Rails 6.1.5よりも前（Rails 6.1.4.7など）では、"cannot load such file -- net/smtp"というエラーメッセージが表示されるため、net-smtp gemを追加すれば直ることが予想しやすいです。

```
LoadError (cannot load such file -- net/smtp):
  
app/mailers/application_mailer.rb:1:in `<main>'
app/mailers/user_mailer.rb:1:in `<main>'
app/controllers/home_controller.rb:3:in `index'
```

![Screen Shot 2022-03-30 at 8.14.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7465/8e13efde-6b97-a463-e1d0-ce7b2a21a965.png)

また、以下のPRでnet-smtpが自動的にインストールされるようになったため、Rails 7.0.1以降ではこの問題は発生しません。

https://github.com/rails/rails/pull/44083

### Rails 6.1.5でだけ、このエラーが発生する理由

では、なぜRails 6.1.5で"uninitialized constant Mail::TestMailer"というエラーが出るのかというと、Rails 6.1.5の例外処理に問題があるからです。

```ruby
# frozen_string_literal: true

begin
  require "mail"
rescue LoadError => error
  if error.message.match?(/net-smtp/)
    $stderr.puts "You don't have net-smtp installed in your application. Please add it to your Gemfile and run bundle install"
    raise
  end
end
```

https://github.com/rails/rails/blob/v6.1.5/actionmailer/lib/action_mailer/mail_with_error_handling.rb

`error.message`の中身は"cannot load such file -- net/smtp"になっているため、上記コードの正規表現は、

```diff_ruby
-if error.message.match?(/net-smtp/)
+if error.message.match?(/net\/smtp/)
```

としなければなりません。

このif文が真にならないため、net-smtpのLoadErrorが発生しても完全に無視され、mail gemがloadされないままサーバー起動するため、`Mail::TestMailer`を参照するタイミングでエラーが発生します。

~~この問題は以下のPRで修正されているため、Rails 6.1系の次回リリースで修正されるものと思われます。~~

https://github.com/rails/rails/commit/8687a4faacb0ec58f250ca072f7479a37e30fe71

[Rails 6.1.6がリリースされ](https://rubyonrails.org/2022/5/9/Rails-7-0-3-6-1-6-6-0-5-and-5-2-8-have-been-released)、 "You don't have net-smtp installed in your application. Please add it to your Gemfile and run bundle install" というエラーメッセージが意図通り出力されるようになりました。

https://github.com/rails/rails/compare/v6.1.5...v6.1.6#diff-9147a2397f91d1ff5151ba2569aaae244a776ff9ecf114491c612ae770d54360R6
Wordpressでarchive.phpを表示させる方法

## はじめに
これは、WordPressで投稿をつかってお知らせを表示している場合の解説です。

## 1. 管理画面のパーマリンク設定を、/%category%//%postid%/に設定

## 2. 管理画面の投稿>カテゴリーから、スラッグにnewsと設定した新しいカテゴリを作る（すでにカテゴリがいくつかある場合は、親カテゴリにする）

## 3. ヘッダーやトップページのリンクを、<?php echo $root_url ?>news/とする。
<?php echo $root_url ?>の部分は、独自で定義したルートURL
エラー：Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?が出た場合の対処法

下記のような感じで、Dockerに関するコマンドを打つとエラーが出る。どうやらDockerが起動していないことで起きるエラーのようです。
```
 % docker ps
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
```


ちなみにバージョンは以下の通りです。

```
% docker --version
Docker version 20.10.13, build a224086
```

※試したこと

```
% systemctl start docker
zsh: command not found: systemctl
```
```
% service start docker
zsh: command not found: service
```

```
% systemctl enable docker
zsh: command not found: systemctl
```

起動中のコンテナ表示

```
% sudo docker container ls -a
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
```

などなど、検索してそれっぽいのが出てきたら片っ端から打ってみましたが全部ダメっぽいですね、、、
↓

解決法：アプリをクリックして起動させる。
 
これでひとまず解決しました。
ただCUIで操作できないのは問題ですね、、原因がわかったら追記します。

開発環境
mac OS バージョン11.6
エディタ
VScode
Windowsにgo言語をインストールする方法

1. [Go言語の公式ページ](https://go.dev/dl/)　からmsiファイルをダウンロードする。
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/60a8923e-7659-eefa-ac74-d34f11bdcea6.png)
2. ダウンロードした `go1.18.windows-amd64.msi` をダブルクリックする。
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/4a6a013c-7bf2-317b-8144-afad9e3e9372.png)
3. `Next` を押下する。
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/ab4a539e-e2ec-2943-5cc6-a5e6a649785d.png)
4. `Next` を押下する。
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/0e551d60-a8c2-fcef-4c4b-4c310a3624cb.png)
5. Go言語のインストール先を指定して、 `Next` を押下する。
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/1a4e4fb4-7f00-ccb4-47f0-0b6692be23db.png)
6. `Install` を押下する。
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/3b4b6199-733a-0896-12b2-63523631094b.png)
7. `Finish` を押下する。
![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/4bf2f95e-2b62-dea5-27df-cccb09bc6677.png)
8. `windowsキー` を押下して、 `環境変数` と入力する。
![08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/8f31fcfb-2469-b0af-1ec7-87c64474ed39.png)
9. `環境変数(N)...` を押下する。
![09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/c8b742ec-4540-1ad0-2ee6-d9d1024af542.png)
10. `GOPATH` が存在することを確認する。
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/770fbf25-83d7-7536-b38b-cbf132f66466.png)
11. ユーザ環境変数の `path` を選択して、 `編集` を押下する。
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/3c2c68de-42eb-66ac-5716-ce756ed9714f.png)
12. `%USERPROFILE%\go\bin` が存在することを確認する。
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/98eaf7fe-2185-3ee8-c5dc-431a8db22a63.png)
13.  システム環境変数の `path` を選択して、 `編集` を押下する。
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/9b8251e8-9ab0-0572-d6e9-9653d188935f.png)
14. `インストール先\bin` が存在することを確認する。
![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/53c66c7d-35db-0361-2824-d97d9623ccc6.png)
15. `windowsキー` を押下して、 `cmd` と入力する。
![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/9ff32bc8-f8ed-dfe2-e3ee-d1cfa87ac133.png)
16. コマンドプロンプトに `go version` と入力して、 `go version go1.18 windows/amd64` と表示されれば成功。
![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/ad3d6ee9-91c4-c30b-eb85-044c48258ec1.png)
React18に上げたら描画の更新がうまくいかなくなった件のメモ

## 概要
React18に上げたタイミングで、storeで値を書き換えても、それが画面に伝播しない状態になった。
結論からいうと、不適切な場所でReact.StrictModeを使用していたのが原因であった。

## 修正箇所

**修正前**

```tsx
  <Router basename={'cartagraph-gamebook'}>
    <React.StrictMode>
      <Provider store={store}>
        <App />
      </Provider>
    </React.StrictMode>
  </Router>
```


**修正後**
```tsx
<Router basename={'cartagraph-gamebook'}>
    <Provider store={store}>
      <React.StrictMode>
        <App />
      </React.StrictMode>
    </Provider>
  </Router>
```

## 参考
[react - strict mode](https://ja.reactjs.org/docs/strict-mode.html)
[React開発環境ではなぜかコンポーネントが2回描画されるのか判った！](https://www.ey-office.com/blog_archive/2021/06/30/i-found-out-why-the-component-is-drawn-twice-in-the-react/)
STM32G031で9600bpsのソフトウェアシリアルのライブラリ化


x OB(オプションビット)は、(2)GPIO

目的
ソフトウェアシリアルのテスト
シリアルの出力先は、PA0
追加方法は、新規タブ


![o_con296.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/b45221bf-5b8c-12d5-2258-bcfe92501a17.jpeg)



![o_con279.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/284181ce-4fc7-419e-aa24-cf1c4e359f7e.jpeg)



![o_con297.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/2a369df1-0e7a-bad1-fdcb-ab4cf424a641.jpeg)



![o_con298.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/ea72e01f-d42f-7e11-0874-e65ac0757e1d.jpeg)


Arduino ファイル分割　で検索するといろいろ出てくる


引用


https://bellitblog.net/2021/01/07/arduino-file-create/



メインプログラム



```c++


//SER_LB_9600_031_1

#include <Arduino.h>

#include "SER_9600_031_1.h"

//初期化
void setup()
{

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

} //setup


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

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

} //loop



```



SER_9600_031_1.hのプログラム



```c++



#ifndef TEST_H
#define TEST_H

//SER_9600_031_1.h


#define TX1      PA0  // 4pin
#define UART_DELAY 102   //  9600bps ok 031


#define DW   digitalWrite


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


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


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

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

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

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

  return (0);
}


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

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

  } //while

  //戻り値
  return (0);
}


//実体の作成
_pc pc;


#endif




```
cscの作法 その76

# 概要
cscの作法、調べてみた。
WebBrowserでhtml5test.comのスコア確認やってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/9744257b-2df7-8ef1-5065-bde888785edd.png)

# サンプルコード

```

using System;
using System.Windows.Forms;
using System.Drawing;

class form1: Form {
	WebBrowser wb0;
	form1() {
		Text = "WebBrowser";
		ClientSize = new Size(800, 500);
		wb0 = new WebBrowser();
		wb0.Dock = DockStyle.Fill;
		this.Controls.Add(wb0);
		string url = "http://html5test.com/";
		wb0.Navigate(url);
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}



```

以上。
cscの作法 その75

# 概要
cscの作法、調べてみた。
tcpサーバやってみた。

# 参考にしたページ

https://qiita.com/herozo/items/3c146ec922a32a23bc07

# コンパイル手順

```
>set PATH=C:\Windows\Microsoft.NET\Framework\v4.0.30319;%PATH%

>csc svr.cs

```

# サンプルコード

```
using System;
using System.Windows.Forms;
using System.Drawing;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;

class form1: Form {
	form1() {
		Text = "server";
		ClientSize = new Size(200, 200);
		Button btn1 = new Button();
		btn1.Location = new Point(50, 50);
		btn1.Text = "test";
		btn1.Click += btn1_Click;
		Controls.AddRange(new Control[] {
			btn1
		});
	}
	void btn1_Click(object sender, System.EventArgs e) {
		TcpServer.ClassTcpServer classTcpServer = new TcpServer.ClassTcpServer();
		classTcpServer.ipaddress = "0.0.0.0";
		classTcpServer.port = 49152;
		classTcpServer.timerinterval = 100;
		classTcpServer.DataReceived += new TcpServer.ClassTcpServer.DataReceivedEventHandler(TcpServer_DataReceived);
		classTcpServer.Start();
		Console.WriteLine(">ok");
	}
	private void TcpServer_DataReceived(object sender, TcpServer.DataReceivedEventArgs e) {
		//イベントが発生したとき
		//textBox1.AppendText(e.Message + Environment.NewLine);
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}





```

以上。
【Rails】フォーム送信した値の前後空白改行を削除する（全角スペース削除対応）

Railsで`form_with`のテキストエリアに入力された値の前後の改行や空白を削除したい。

## 実装

特に難しい内容でもないので実コードを書きます。

```ruby:post.rb
class Post < ApplicationRecord
  validates :content, presence: true
  before_save :trim_content

  private

  def trim_content
    content.strip!
  end
end
```

`strip!`メソッドで**前後の改行や空白**を削除できます。
`form_with`から入力した値を加工するチャンスはその他にも`JavaScript`や`Controller`内などありますが、`Model`内でやるのが一番管理しやすいかと思います。

### 全角スペースの削除対応

ちなみに、`strip`や`strip!`メソッドですが、全角スペースは対応していません。
そのため、下記のような文字列の場合は不完全な結果になってしまいます。

```ruby
# 先頭に「半角スペース」「全角スペース」がある
> " 　あい 　うえaお".strip
=> "　あい 　うえaお"
# 「半角スペース」は消えるが「全角スペース」は消えない
```

ので、別のメソッドを作成しました。

```ruby:config/initializers/string_extension.rb
class String
  # 全角スペースを含むstripメソッド
  #
  # @return [String] 短縮された文字列
  def strip_zenkaku
    gsub(/\A[ 　\t\r\n\f\v]*|[ 　\t\r\n\f\v\0]*\Z/, '')
  end

  # 全角スペースを含むstrip!メソッド（破壊的）
  #
  # @return [String] 短縮された文字列
  def strip_zenkaku!
    gsub!(/\A[ 　\t\r\n\f\v]*|[ 　\t\r\n\f\v\0]*\Z/, '')
  end
end
```

やっていることはほぼ`strip`メソッドと同じで、先頭または最後にある特定の文字列を削除しています。
特定の文字列と後ろの方だけ`\0`があるのはリファレンスを参考にしています。

> [String#strip (Ruby 3.1 リファレンスマニュアル)](https://docs.ruby-lang.org/ja/latest/method/String/i/strip.html)
> 
> 空白文字の定義は " \t\r\n\f\v" です。また、文字列右側からは "\0" も取り除きますが、左側の "\0" は取り除きません。

railsの`initializers`の中に定義しておけばいつでも利用できるので、参考にしてみてください。