OmniAICreator/Qiita-1.07M huggingface dataset:
[Flutter + Widget テスト] ウェジットのテキスト文字列をチェックする

# Textの文字列は正しいか確認したい
みなさんはテスト書いてますか？私はあまり書いてないので意識的に書くよう心がけています。今回はFlutterのWidgetテストに関する一件。

`Text`ウェジェットに表示されている文字列を確認しようとすると、以下のようなサンプルが多く見つかります。
```dart
// "hoge"と表示されたウェジェット（Text,EditTextなど）がひとつ存在するか確認
expect(find.text("hoge"), findsOneWidget);
```

これでも目的を達成できますが、次ようなmatcher`withText`が欲しい。

```dart
// 指定したウェジェットに"hoge"と表示されている
expect(find.byWidgetPredicate(yourPredicate), withText("hoge"));
```

よし、作ろう。

# カスタムMatcherの自作
[Dart API - CustomMatcher class](https://api.flutter.dev/flutter/package-matcher_matcher/CustomMatcher-class.html)

要約すれば、検査対象のオブジェクト`actual`からmatcherに渡してチェックする値を取り出す関数`featureValueOf(actual)`を定義ればいいようです。注意として、関数`find.*`で探したウェジェットは`Finder`オブジェクトで返ってきます。

参考： [stackoverflow   Flutter - how to get Text widget on widget test](https://stackoverflow.com/questions/54235752/flutter-how-to-get-text-widget-on-widget-test)

```dart:TextWidgetMatcher
class TextWidgetMatcher extends CustomMatcher {
  TextWidgetMatcher(dynamic stringMatcher)
      : super(
          "Text Widget with",
          "string",
          stringMatcher,
        );

  @override
  Object? featureValueOf(actual) {
    if (actual is Finder) {
      final widget = actual.evaluate().single.widget;
      if (widget is Text) {
        return widget.data;
      } else {
        throw ArgumentError("Text widget expected, but actual: $widget");
      }
    }
    throw ArgumentError("Finder expected, but actual: $actual");
  }
}
```

あとは適当に`withText`関数を用意すれば完成！
```dart
Matcher withText(dynamic stringMatcher) => TextWidgetMatcher(stringMatcher);


// 指定したウェジェットに"hoge"と表示されている
expect(find.byWidgetPredicate(yourPredicate), withText("hoge"));
```
研究室に置いたCentOSの計算機をネットワークに繋いだ方法

<details><summary>更新履歴</summary>

- タイトルを「研究室に置いたCentOSの計算機に自宅からsshできるようにした方法」→「研究室に置いたCentOSの計算機をネットワークに繋いだ方法」に変更。
- "nmcli d"に"nmcli device"を追記。

</details>

# やったこと

前所属で使っていた計算機1と新しい計算機2の2台(CentOS)を現所属の研究室に置き、有線でネットワークに繋いだ。
さらに、自宅から研究室のネットワークにVPNで繋ぎ、計算機にsshできるようにした。
そのためにやったことは以下の通りである。

- 固定IP申請のためにMACアドレスを調べる。
- ネットワークに繋がったことを確認する。

その他参考になった以下の情報もまとめる。

- OSのバージョン確認の仕方。
- パスワードを入力せずにsshする(公開鍵)設定。
- ポートフォワーディングのためのポート番号には役割があるという話。

# まずは計算機をネットにつなぐ

計算機の電源を入れ、有線LANに繋ぐ。ちなみにこの有線はハブを通している。

### MACアドレスを調べる(CentOSのターミナルから)

~~~
$ ifconfig
~~~

これの"ether"がMACアドレスである。しかし、複数あり(eno1, virbr0)、どれが本物かわからない。
結論を言うと"eno1"の"ether"がMACアドレスであった。

### MACアドレスを調べる(CentOSの設定から)

「設定」→「ネットワーク」→「有線」→「設定」→「ハードウェアアドレス」= MACアドレスである。
これより"eno1"の"ether"という結論が得られた。

### ついでに(初期設定なら問題ないと思うが)

「自動接続」にチェックを入れる。
「identity」の「MACアドレス」＝「ハードウェアアドレス」になっている。
「IPv4」も「IPv6」も「自動」にチェックを入れる。「DNS」も「ルート」も「自動」にチェック。
ちなみにここで、「IPv4」が前置いていたところの手動設定になっていたため、なかなか繋がらなず悩まされた。

### 固定IP申請受理後、ネットが繋がっていることの確認

~~~
$ nmcli d
~~~

もしくは

~~~
$ nmcli device
~~~

これで例の"eno1"が"接続済み"になっていればOK。
なっていなければ以下のコマンドを入力。

~~~
$ nmcli connection up eno1
~~~

Firefoxでインターネットが見られればOK。

### (おまけ)計算機の名付け

1台なら何でもいい。しかし複数台あると名付けも苦労する。
そこで私は"(任意の単語)"+"購入年の西暦下二桁"としている。
例えば"apple20", "apple21"という感じである。
ただし、一年に複数台購入することはないと思っている。

# おまけ

今回必要になったマイナー作業についての情報も残しておく。

### OSのバージョン確認の仕方

~~~
$ cat /etc/*release
~~~

### 公開鍵設定

すでに鍵は作ったことがあるという前提の話である。
自分のノートパソコンで以下のコマンドを入力する。

~~~
% ls ~/.ssh/
~~~

"id_rsa", "id_rsa.pub"みたいなのがあれば作ったことがあるはずである。
あとは自分のノートパソコンで以下のコマンドを入力する。

~~~
% ssh-copy-id -i ~/.ssh/id_rsa.pub <user name>@<ip address>:
~~~

他にもやり方はあるがこれだと手間がかからないと思われる。

### ポート番号の話

ここでは説明はしないが、sshするときにポートフォワーディングという方法で研究室の計算機とデータをやり取りしている。
そのポート番号には役割がある。
例えば以下の通りである。

- 22: ssh
- 5900: vnc

計算機1と計算機2で、あちら側は22番ポートだが、こちらのノートパソコン側はそれぞれ空いている別々のポート番号を使わないと上手くいかなかった(気がする)。
私は全然詳しくないので具体的なことは(今は)書けない。

# おわりに

こうやってまとめると簡単に設定できそうな気がするが、2-3時間かかった気がする。
(自分に向けて)また所属が変わったときは頑張ってほしい。
【クソアプリ】個人開発三つ目だがアウトプットの話をしようと思う【アウトプットは大切という話】

まず宣伝させてください。。

今回もDjangoでアプリを作成しました。
みんなの宝箱というアプリで、宝物を入れて、それをガチャの要領で開けることができるアプリです。

https://takara.quality-of-life1.com/

ログインなしで遊べますが、ログインするとお宝コレクションができるマイページが使えます。
よければテストユーザーで確認してみてください。
アドレス：test@example.com
パスワード：0000aaaa
でログインできます。

今回はこちらの作成に当たり、アウトプットはどのくらい大切かという話をしていきたいです。

:::note info
この記事で伝えたいこと
・勉強してるのにできるようにならない人が成長するには
・とりあえず作る大切さ
・アウトプットした分だけ成長が見込める
・覚えようとしない、その場で調べる
:::

目次
1. プログラミングの勉強しているのに成果が出ない
2. 【アウトプット大事】１個目より２個目のほうが圧倒的早く作成できる
　1. とりあえず、一つアプリを作るとやることが明確化されてくる
　2. 前回の作成物から、コピペできる箇所がある
　3. 一度経験すると忘れていてもすぐ思い出せる
3. アウトプットした分だけ楽になる
4. できるようになるには、勉強するときは覚えようとしない
5. 最後に

# プログラミングの勉強しているのに成果が出ない人
勉強しているのに成果が出ない方はアウトプットに重点を置いて勉強してみましょう。
やり方としては
- 本や参考サイトをまねしないで、自分で考えて新しいものを作る。
- 何をしたいか決めてから勉強を始める
- 勉強に時間を割かない、実際に何か作成してみる
です。

# 【アウトプット大事】１個目より２個目のほうが圧倒的早く作成できる

なぜ早くできるのか、それは
- とりあえず、一つアプリを作るとやることが明確化されてくる
- 前回の作成物から、コピペできる箇所がある
- 一度経験があれば、忘れていてもすぐ思い出せる

の３点があるからだと思います。
前回はアプリ

yokatter.quality-of-life1.com

では、ログイン機能なし、デザインもシンプルなのに１週間はかかりました。
しかし今回のアプリは、デザインも作成（相変わらず苦手だが）、ログイン機能ありなのに四日ほどで作成できました。
それは先ほど挙げた三点があったからだと思います。

## とりあえず、一つアプリを作るとやることが明確化されてくる

今までアプリを作ったことがない人は、何から始めたらいいのか、何が必要なのかがわからないのです。

一つ目の作成の時は私もそうでした。
色々調べながら、アプリを作る手順を調べ、進めていくので、かなり時間がかかってしまいました。
どんなページが必要で、どんなリンクが必要なのかなど初歩の初歩から悩みました。

しかし、２つ目のアプリを作るときには、１つ目の経験から、何が必要で何から始めるというのが明確になったので、かなり時間が短縮したと思います。

## 前回の作成物から、コピペできる箇所がある
これも重要です。
今回私はかなり前回のアプリから、コピペしています。
今回コピペで済んだ点は、
- 保存画像の圧縮
- 保存画像のリネーム
- 初期設定
- デプロイ時の設定
です。これだけでもかなり時間削減になります。

ただ一つの注意事項として、コピペ箇所を探すのに時間がかかることもあるので、gitを使い、こまめにコミットしていくと、作業ごとの履歴ができるので、自分がどこを追加し、何のために追加したかなどもこまめにコメントしていきましょう。

## 一度経験すると忘れていてもすぐ思い出せる
これは何事にもそうだと思うのですが、一度経験すると、忘れていてもすぐ思い出せます。
これがアウトプットの一番重要な部分だと思っています。
知識はすぐ忘れてしまうが、経験はなかなか忘れません。

今回は例えば、新規プロジェクトの作成方法など、忘れていましたが、調べればすぐ思い出せました。

## アウトプットした分だけ楽になる
これはほかの勉強法でもよく見ますが、アウトプットが大切です。
なぜなら
- 難しいと思っていたことが実はそんなに難しくなかったとわかる
- わからないことがストレス、一度わかるとストレスが少なくできる
- エラーの解消ができるようになる
- 一個作ると達成感が味わえる
からです。

できるだけアウトプットをしていきましょう。
# できるようになるには、勉強するときは覚えようとしない
プログラミング学習をする上ですべて記憶するの無理だと断言します。
これは、覚えるとなるとかなりの情報を記憶しなければいけないからです。
「知っていること」と「できること」は別物です。

正直私もはじめは何冊もの本をこなしできる気になっていました。
しかし実際、アプリを作り始めるときは、まったく応用できずやり方も忘れていたり、同じことを何度も調べながら少しずつできるようになってきました。

なので自分でやってみて経験する。
これが「できるようになる」ために大切なことだと思います。
# 最後に
私もまだまだ初心者で、そんな奴に言われたくないと思うかもしれません。
しかし、人生で初めてアウトプットに意識を置くことで自分の成長を実感しています。

よく見るアウトプットの話ですが、アウトプットするのは大変です。
ただ楽しさもあります。
「知りたい」ではなく「できるようにしたい」のであればアウトプットしましょう。
一緒に頑張りましょう。
基板設計をする際の注意事項

一人で基板設計をしていると、設計ミスに気付かないことが
よくある。
なので自分用のチェックリストを作成してみた。
他にもチェックした方がいいなどありましたらアドバイスお願いします！

---
- [ ] 配線が直角になっていないか
- [ ] パスコンが正常な位置にあるか
- [ ] ダンピング抵抗は必要か。必要であれば適切な値であるか
- [ ] RESET配線にガードがあるか
- [ ] GNDベタがアンテナになっていないか（ビアでアンテナ対策）
- [ ] ビアが一定の間隔で打たれているか（目安10mm）
- [ ] リターン電流が大きく迂回していないか
- [ ] キャパシタの順番が正しいか
- [ ] アナログとデジタル配線が交差していないか
- [ ] 未使用の端子は、GNDに接続しているか
- [ ] 逆流、静電気、サージ対策はされているか（ツェナーダイオード、バリスタなど）
- [ ] 部品の下に電源配線を通していないか
- [ ] コネクタ部分は配線が強化されているか（ディアドロップ形状）
- [ ] 外周がベタ塗りされているか
- [ ] 30mmを超える直線の配線がないか
- [ ] 異なる電源ラインにGNDが挟まれているか
- [ ] テストピンが配置されているか
- [ ] コイル、水晶発振子の下に配線がないか
- [ ] ICの下はGNDになっているか
- [ ] 浮島がないか
[Python]sympyを使って多項式から任意の着目する変数の係数を求める方法

```python
import sympy as sp

sp.var('x1, x2, x3')		# 着目する変数
sp.var('c1, c2, c3, c4, c5')	# 係数
expr = c1*x1 + c2*x2 + c3*x3 + c4*x1*x2 + c5	# 式を定義

expr_poly = sp.poly(expr, x1, x2, x3)	# x1,x2,x3に着目した多項式オブジェクトを作成
x1_coef = expr_poly.nth(1, 0, 0)	# x1の係数
x2_coef = expr_poly.nth(0, 1, 0)	# x2の係数
x3_coef = expr_poly.nth(0, 0, 1)	# x3の係数
x1_x2_coef = expr_poly.nth(1, 1, 0)	# x1*x2の係数
constant = expr_poly.nth(0, 0, 0)	# 定数

print(x1_coef, x2_coef, x3_coef, x1_x2_coef, constant)
# 実行結果 -> c1 c2 c3 c4 c5
```
  <br>

(補足)polyやnthの引数は可変長引数になっているので引数の展開を使うとリストのまま扱えて便利
```python
variableList = [x1, x2, x3]
expr_poly = sp.poly(expr, *variableList)
x1_coef = expr_poly.nth(*[1, 0, 0])
x2_coef = expr_poly.nth(*[0, 1, 0])
x3_coef = expr_poly.nth(*[0, 0, 1])
x1_x2_coef = expr_poly.nth(*[1, 1, 0])
constant = expr_poly.nth(*[0, 0, 0])
```

### 参考資料
[Sympy公式ドキュメント](https://docs.sympy.org/latest/modules/polys/reference.html?highlight=nth#sympy.polys.polytools.Poly.nth)
Rustでトレイトを使わずに継承する裏技


参照外し演算子は暗黙に呼び出されるので、それをオーバーロードしてしまえば継承(もどき)ができる。

# 例
```rust
struct Hoge{}

impl Hoge{
    fn say_hoge(&self){println!("hoge")}
}

struct Moge{
    hoge:Hoge
}

//裏技
use std::ops::Deref;
impl Deref for Moge{
    type Target = Hoge;
    fn deref(&self) -> &Self::Target {&self.hoge}
}

impl Moge{
    fn new() -> Self {Moge{hoge:Hoge{}}}
    fn say_moge(&self){println!("moge")}
    fn say_hoge_moge(&self){
        self.say_moge();
        self.hoge.say_hoge(); //内部からアクセスする時は普通に呼び出さないといけない
    }
}

fn main(){
    let moge = Moge::new();
    moge.say_hoge(); //内包するメンバのメソッドを直接呼び出せる
    moge.say_moge(); //追加されたメソッドも普通に呼び出せる
}
```

# 感想
スマートポインタが勝手に解決されるのを見てて気が付いた。
特定のメンバとそれ自身を同一であるかのように振舞わせたい時、ラッパーメソッドを沢山作らなくても良い。
ただ、これだとポリモーフィズムが実現されてないので普通にトレイトを作った方が良い。トレイト作った上で、トレイトは弄りたくないけど外部からは内部の構造体に簡単にアクセスできるようにしたいとかそういう時しか実用性無さそう。
nginxでnuxtjsを利用した静的サイトを立ててAWSのELBでhttps化したらリロードができない

# はじめに

ローカルでnginxでnuxtjsで作ったサイトをテストして、いざ公開しようとしたら、リロードボタンを押すと読み込みできなかった話。

## 現象

nuxtjsでSPAで遷移する場合、URL欄に/loginなどが表示されます。
これは内部的には、フォルダになっており、/login/index.htmlにアクセスします。

一般的なwebサーバの仕組みは以下になります。

1. documentRootに同じパスのファイルがあるかチェックし、あったらそれを返す。
2. 同じ名前のフォルダがあるかチェックし、あれば、301 redirect で/付きのpathを返す
3. pathが/で終わっている場合は、設定により、index.htmlなどを返す。

今回は、2で、301 redirectするのですが、nginx的にはロードバランサーは知らないので、リダイレクト先に http://ホスト/フォルダ/ を返してしまうためです。



結局以下の設定ファイルでうまくいきました。
```
server{
    listen       80;
    
    auth_basic           "closed site";
    auth_basic_user_file /etc/nginx/conf.d/htpasswd;
    
    location = /_alive {
        return 200;
        satisfy any;
        allow   all;
    } 
    location ^~ / {
        root   /usr/share/nginx/html;
        index  index.html;
    }
    if ($http_x_forwarded_proto = http) {
      return 301 https://$host$request_uri;
    }
}
```

ヘルスチェックは /_alive
nuxtjsで作成したファイルは/usr/share/nginx/html下に配置します。

ELB経由でアクセスがあった場合、http_x_forwarded_protoにプロトコルが入ってくるそうです。
ここを != httpsにしているページもありましたが、そうするとヘルスチェック用の /_alive も転送されてしまうので、ロードバランサーがつながりません。
（あとローカルでテストもしにくいです。）
AzureAD認証を使ったSPAでAPIサーバー側でグループクレームがどうしても取れなかった

## Azure ActiveDirectory (B2Cでない方)を認証に使う
ログインユーザーの権限管理でサンプルにもある、ロールベースやポリシーベースを使おうとしていた。
AzureAD(Free)での権限管理はいろいろ方法があるみたい。ドキュメントもちょっと散らかってる感あってわかりにくい…

## 紹介されているやりかた（全部ではないかも）
### アプリケーションにアプリ ロールを追加してトークンで受け取る
参照）https://docs.microsoft.com/ja-jp/azure/active-directory/develop/howto-add-app-roles-in-azure-ad-apps
ちなみにですがB2Cのテナントだと画面が違います。アプリロールやトークン構成のメニューは**ありません。**
ただB2Cでも同じ設定はマニフェストの編集により可能です。
(ずっとB2Cの画面で探しててそれにもハマった…）

#### 参考：ロールベース
https://docs.microsoft.com/ja-jp/aspnet/core/security/authorization/roles?view=aspnetcore-6.0

### テナントにカスタムロール追加
https://docs.microsoft.com/ja-jp/azure/active-directory/roles/custom-create
AzureAD(Free)では使えません。
ADテナント全体にロールを作成する方法（ビルトインロール以外）

### ポリシーベース
一番カスタム可能な内容、ユーザークレーム（属性）に条件付与してポリシーを適用できたりする。
ここでグループクレームからポリシーを適用しようとしたが、groupがAPI側で取れていなかった。（後述）
参考）
https://docs.microsoft.com/ja-jp/azure/active-directory/hybrid/how-to-connect-fed-group-claims
サンプル）
https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/blob/master/5-WebApp-AuthZ/5-2-Groups/README.md

### クレームベース
クレームベース∈ポリシーベース
ということかな。

## ユーザーをグループに割り当ててグループによりポリシーを適用しようとした。
ここから本題

今回の構成はSPA（Blazor WASM＋ASP.NET Core）なので、公式参照しながら設定
参考）
https://docs.microsoft.com/ja-jp/aspnet/core/blazor/security/webassembly/hosted-with-azure-active-directory?view=aspnetcore-6.0
このへんから。

逸る気持ちを抑えて、じっくり読めばちゃんと動くはず。いらちを発動するとよくハマるので。笑

では次に別のチュートリアル参照しながら、特定のグループに所属しているユーザーのみコールできるAPI（ASP）を作成する。

https://docs.microsoft.com/ja-jp/azure/active-directory/develop/active-directory-optional-claims?WT.mc_id=translate-blog-yoterada#configuring-groups-optional-claims
このへんでまずはクライアント（SPA側）にGroupsが入るように設定した。
ちなみにこのドキュメント内の「[管理] で、 [トークン構成] を選択します。」はB2Cテナントでは**表示されません。**（再

ここでハマりポイント（自分的）だったのはトークン発行されるのはSPA側なので、上記のトークン構成はクライアント側しか**やっていなかった。**

本当はサーバー側も設定が必要だった。

### 起こっていた状態
id_tokenにはgroupsのclaimがあったが、
access_tokenにはgroupsが入っていない。
→ASP側でgroupsが判別できない。

jwt.ioで確認しまくった…

## やったこと（解決）
サーバー側アプリケーションのトークン構成でもgroupsの設定をする。


### ちなみに、Audienceがない、と言われてログインもできないとき
https://docs.microsoft.com/ja-jp/aspnet/core/blazor/security/webassembly/hosted-with-azure-active-directory?view=aspnetcore-6.0#app-settings
上記参照、ちょっと日本語わかりにくいがAudienceの設定がsettings.jsonあたりに必要なようす。
Rで連続する秒などのタイムスタンプのベクトルを作る

# 0.連続する日付のベクトル
Rで連続する日付のベクトルを作るには以下の記事のようにseq()関数を使います。

R言語で連続する日付のベクトルを作る｜Colorless Green Ideas 

https://id.fnshr.info/2017/11/28/r-seq-date/

次の例では2021-12-29から2022-01-02の日付を生成しています。
```R:連続日付.r
seq(as.POSIXlt("2021-12-29"), as.POSIXlt("2022-01-02"), by = "day")
```
```：結果
[1] "2021-12-29 JST" "2021-12-30 JST" "2021-12-31 JST" "2022-01-01 JST"
[5] "2022-01-02 JST"
```

連続させる間隔を指定するbyには以下のような文字列が指定できます。(@WolfMoon さん、ご指摘ありがとうございます)
- "sec"(秒)
- "min"(分)
- "hour"(時間)
- "day" （日）
- "DSTday"（日　サマータイム考慮）
- "week" （週）
- "month" （月）
- "quarter" （四半期）
- "year" （年）

この記事では、タイムスタンプの時分秒で連続したベクトルをつくりたいと思います。

# 1.連続する秒のベクトル

秒の場合は、開始と終了にタイムスタンプを与えてby="sec"またはby=1にします。by="senconds"は指定できませんでした。
以下の例では2021-12-31 23:59:57から2022-01-01 00:00:01までの1秒ごとに連続するタイムスタンプを生成しています。

```R:連続秒.r
seq(as.POSIXlt("2021-12-31 23:59:57"),as.POSIXlt("2022-01-01 00:00:01"),by="sec")
```
```：結果
[1] "2021-12-31 23:59:57 JST" "2021-12-31 23:59:58 JST"
[3] "2021-12-31 23:59:59 JST" "2022-01-01 00:00:00 JST"
[5] "2022-01-01 00:00:01 JST"
```

# 2.連続する分のベクトル

秒の場合は、開始と終了にタイムスタンプを与えてby="min"またはby=60にします。60秒ごとという意味になります。
以下の例では2021-12-31 23:57:00から2022-01-01 00:01:00までの1分ごとに連続するタイムスタンプを生成しています。

```R:連続分.r
seq(as.POSIXlt("2021-12-31 23:57:00"),as.POSIXlt("2022-01-01 00:01:00"),by="min")
```
```：結果
[1] "2021-12-31 23:57:00 JST" "2021-12-31 23:58:00 JST"
[3] "2021-12-31 23:59:00 JST" "2022-01-01 00:00:00 JST"
[5] "2022-01-01 00:01:00 JST"
```

# 3.連続する時間のベクトル

時間の場合は、開始と終了にタイムスタンプを与えてby="hour"またはby=60\*60にします。60秒×60分＝1時間ごとという意味になります。
以下の例では2021-12-31 21:00:00から2022-01-01 01:00:00までの1時間とに連続するタイムスタンプを生成しています。

```R:連続時間.r
seq(as.POSIXlt("2021-12-31 21:00:00"),as.POSIXlt("2022-01-01 01:00:00"),by="hour")
```
```：結果
[1] "2021-12-31 21:00:00 JST" "2021-12-31 22:00:00 JST"
[3] "2021-12-31 23:00:00 JST" "2022-01-01 00:00:00 JST"
[5] "2022-01-01 01:00:00 JST"
```

■参考
-  seq.POSIXt function - RDocumentation 


https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/seq.POSIXt
   - time - Sequence with fractional second intervals in R - Stack Overflow 

https://stackoverflow.com/questions/34927600/sequence-with-fractional-second-intervals-in-r


■テスト環境
R 4.0.5
Windows 10 64bit
Jetson AGX XavierとWindows10 PCをVNCで接続

Jetson AGX XavierとWindows10 PCをVNC接続したときの備忘録です。

環境
JetPack4.6.1

ターミナルを起動し、以下をコピペしていきます。最後に再起動が入ります。

```
cd /usr/lib/systemd/user/graphical-session.target.wants
sudo ln -s ../vino-server.service ./.
gsettings set org.gnome.Vino prompt-enabled false
gsettings set org.gnome.Vino require-encryption false
gsettings set org.gnome.Vino authentication-methods "['vnc']"
gsettings set org.gnome.Vino vnc-password $(echo -n 'password'|base64)
sudo reboot
```

passwordは任意の文字でOKです。passwordをhello_jetsonにする場合は、
```
gsettings set org.gnome.Vino vnc-password $(echo -n 'hello_jetson'|base64)
```
とします。

あとは、Windows10 PCのVNC ViewerからJetson AGX XavierのIPアドレスを指定して接続できます。パスワードは上で指定したものを入力します。

参考ページ
https://developer.nvidia.com/embedded/learn/tutorials/vnc-setup
量子回路の出力状態ベクトルを求めたい・・・手計算ではなく、パソコンで。

# 量子回路の出力状態ベクトルを求めたい

量子計算について学習するとき、「今の量子回路の出力状態を求めたいなー」って思う時があります。
もちろん、手計算で求められます。
でも回路が複雑になってくると、思いのほか面倒です。
（あるいは単に面倒でやる気が出ない時）
そんな時に、パソコンを使って簡単に求める方法について解説します。

# 1. Qiskitをインストールする

ネットを探したら方法はいくらでも見つかりますので、省略します。


# 2.Qiskit textbookをインストールする
以下のコマンドを実行します。

```
pip install git+https://github.com/qiskit-community/qiskit-textbook.git#subdirectory=qiskit-textbook-src
```

# 3. 以下のプログラムを実行

```python
from qiskit import *
from qiskit_textbook.tools import array_to_latex

# （1）出力状態を求めたい量子回路を作る。（ここでは例として、簡単な回路を作ります）
qc = QuantumCircuit(1)
qc.h(0)

# あとはコピペでOKです。
# （2）シミュレーションして、状態ベクトルを取得します。
backend = Aer.get_backend('statevector_simulator')
final_state = execute(qc,backend).result().get_statevector()

# （3）綺麗に表示します
array_to_latex(final_state, pretext="\\text{Statevector = }")

```
latexを使うので、Jupiter Notebook上で実行するのが良いと思います。

# 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252164/23a99732-d703-129d-b061-b67796ef92d4.png)

# 具体例を紹介

$CNOT$ゲートと$H$ゲートで「もつれ状態」を作ることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252164/41dd0576-2e55-8ca5-ee39-c4d9a7e51966.png)

この回路の出力状態を見てみましょう。

```python
from qiskit import *
from qiskit_textbook.tools import array_to_latex

# （1）出力状態を求めたい量子回路を作る。（ここでは例として、簡単な回路を作ります）
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0,1) # (control, target)

# あとはコピペでOKです。
# （2）シミュレーションして、状態ベクトルを取得します。
backend = Aer.get_backend('statevector_simulator')
final_state = execute(qc,backend).result().get_statevector()

# （3）綺麗に表示します
array_to_latex(final_state, pretext="\\text{Statevector = }")

```

# 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252164/4039f61e-27c1-cd25-e8c0-5c548882422f.png)


つまり、$CNOT|0+\rangle = \frac{1}{\sqrt{2}}(|00\rangle+|11\rangle)$ということですね。

（この記事は https://qiskit.org/textbook/ja/ch-gates/multiple-qubits-entangled-states.html を参考にしています。）
スマホでUbuntu 22.04を操作する【RDP】

### 設定を開く
![Screenshot from 2022-04-26 13-35-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/fd0e7b4b-0901-3c25-360b-9cc5905247f9.png)

### 共有からRemote Desktopを開く
![Screenshot from 2022-04-26 13-36-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/2cec6097-4e8d-33ea-cd0e-ef8231e3e49f.png)

### Remote Control を有効にする
*Remote Desktop Address*と*User Name*と*パスワード*をメモする。Remote Desktopのトグルを二回押す(再起動)
![Screenshot from 2022-04-26 16-06-33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/75b59b13-08ef-783b-82cf-782969b525d9.png)


### スマホにRDP クライアントをインストール

Android

https://play.google.com/store/apps/details?id=com.iiordanov.freeaRDP&hl=ja&gl=US

iOS

https://apps.apple.com/jp/app/remote-desktop-manager/id1039961293

Kindle Fire

https://www.amazon.co.jp/Devolutions-Remote-Desktop-Manager/dp/B01BH96RKY

### ＋ ボタンを押す
![Screenshot_20220426-155815.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/5c788b7b-7823-6641-d4dc-256294e342d6.png)


### Remote Desktop AddressとUser Nameとパスワードを入力して、フロッピーディスクボタンを押す
![Screenshot_20220426-160832.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/d4c5632c-43f9-4065-4e4f-3d1c8fbcac4d.png)



### Connection💻を押す
![Screenshot_20220426-160851.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/71ccfdf6-ac05-863a-6201-5252b1e83292.png)


### OKを押す
![Screenshot_20220426-161341.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/f86e20b0-bc7f-dd01-96b4-8d37a55720b7.png)



### 接続完了🎉
![Screenshot_20220426-161401.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/c8e56069-1635-2d88-5041-9aa4eb500e90.png)

Android
![ezgif-5-a0b921ed30.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/dddf28b4-f8c4-d4f4-e29a-5ede5462e32c.gif)

iOS
![ezgif-5-1450046cd8.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/030ea0f4-909c-e7ef-2225-123c2676fedc.gif)

Kindle Fire
![Screenshot_2022-04-28-14-06-23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/2ae3c8c3-5628-08c0-c249-fc9f0506f539.png)
メモ:条件演算子(?:)とNull合体演算子(??)の違い

## 概要
つい最近TypeScriptでコードを書いていて、条件演算子(?:)とNull合体演算子(??)の違いに引っかかったので忘れないようにそれぞれの違いと、どこに引っかかったのかをメモした記事です。

## 条件演算子(?:)
条件演算子は以下の形式で使用され、**条件が真値であった場合**に左辺を、**条件が偽値であった場合**に右辺を実行します。
```
条件 ? 左辺 : 右辺
```
JavaScriptで偽値として扱われるのは次の値です。
- false
- 0
- 0n(BigInt)
- 負の値
- 空文字列("")
- null
- undefined
- NaN

そのため、上記の値を条件として利用した場合は全て右辺が実行されます。
```TypeScript
false ? "true value" : "false value"
// false value

0 ? "true value" : "false value"
// false value

"" ? "true value" : "false value"
// false value

null ? "true value" : "false value"
// false value

undefined ? "true value" : "false value"
// false value
```

## Null合体演算子(??)

次にNull合体演算子(??)についてです。

Null合体演算子は以下の形で使用され、*左辺が `null` または `undefined` の場合*に右辺を返し、*それ以外の場合*に左辺を返します。
```
左辺 ?? 右辺
```

自分が引っかかったのがまさにここで、一部の書き方で利用する場合に同様の動作をするため、Null合体演算子(??)は条件演算子(?:)の記述と同じ条件で同じように動作すると勘違いしていました。

そのため、それぞれの演算子に `null` または `undefined` を利用する場合とそれ以外の場合で動作が異なることに気がつかず、想定外の動作が発生した時にはしばらく唸ってました。

もう少し具体的に見ていきます。

上記の説明の通り、Null合体演算子は左辺が `null` または `undefined` の場合に右辺を返します。
そのため、以下の記述はどちらも`value`が`undefined`の場合は`false value`を返し、それ以外の場合はその値を返すという動作をします。
```TypeScript
const value = undefined;
// string | undefined
const result1 = value ? value : "false value";
// false value

const result2 = value ?? "false value";
// false value
```

この場合は、結果的にNull合体演算子(??)で条件演算子(?:)の記述を省略した書き方になっています。

では、Null合体演算子(??)が条件演算子(?:)と同じ条件で同じように動作するだと勘違いしたまま次のようなコードを書くとどうなるでしょうか?
```TypeScript
const number = Number(process.env.NUMBER) ?? 1
// process.env.NUMBERは string | undefined

// numberを利用した処理
```

上記のコードでは、`number`に必ず数値が入ることを想定しています。

Null合体演算子(??)が条件演算子(?:)と同じ条件で同じように動作する場合、`process.env.NUMBER`が偽値の場合`Number(process.env.NUMBER)`も偽値(`NaN`)のため`number`は`1`となり、以降の処理でも数値として扱われるため想定通りに動作します。

ただし、実際にはNull合体演算子(??)は 左辺が null または undefined の場合のみ右辺を返す演算子なので、左辺が`NaN`の場合はそのまま`NaN`を返します。
そのため、以下の`number`を利用した処理で想定していない動作をすることになります(というか実際になりました)。

ちなみに以下のように書くと、想定している通りに処理ができます。

```TypeScript
const number = Number(process.env.NUMBER || "1")

// numberを利用した処理
```


このように一部の状況では省略記法のように書くことができても根本の動作が違う場合、気がつかずにバグを生む可能性があります。

なので、新しいものを使うときはまずドキュメントを読みましょうという自戒を込めた記事でした。

## 参考文献
- [条件 (三項) 演算子 - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Conditional_Operator)
- [Null 合体演算子 (??) - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator)
Javascriptの基礎 概要編

## JavaScriptとは

HTML/CSSで作られたサイトは静的なものになってしまします。
※突き詰めるとCSSでアニメーションのようなものも作れるみたいですが、僕は初学者なのでまだ理解していません、、すみません。

ただ、JavaScriptを用いることで、サイト自体に『動き』を出すことが可能になります。

例えば、、、
- 入力の際に間違いや、空欄があったときのエラーメッセージ
- googleの検索フォームで、文字を入力時に予測変換で出てくる
- 地図の拡大や縮小

その他にも様々な場面で使われています。

2021年時点ですが、世界的に見てもJavaScriptは一番習得されている技術のようです。

また移り変わりの激しいITの業界でもこの言語だけは変化することなく、常に求められている言語のようです。。

**現在のWebサイトには欠かせないプログラミング言語**としてJavaScriptは習得した方がいいと思いました。

基礎から勉強していきたいと思います。

## まず第一歩目として

まず実際にchrome表示させてみたいと思います。

使用する物
- Visual Studio Code
- Google Chrome

この2つでやっていきたいと思います。

まず、sample.htmlというファイルを作成し、同じディレクトリ内にsample.jsというファイルを作成してください。
そしてそのファイルをデスクトップなどに保存して準備完了です。

## JavaScriptで"こんにちは"と表示させてみる

方法としては2つあります。

**１つ目はHTMLファイルに直接記述する**

```sample.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
  </head>
  <body>
    #scriiptタグで囲み、その中に記述する
    <script>
      alert('こんにちは');
    </script>
  </body>
</html>
```
**２つ目は、javascriptファイルを作り、そこに記述する**

```sample.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
  </head>
  <body>
    #ファイルパスを指定してあげる
    #今回は同一のフォルダ内にjsファイルを作成
    <script src = "sample.js"></script>
  </body>
</html>
```
```sample.js
alert("こんにちは");
```
上記２つのやり方で表示内容は同じです。

## まとめ

javascriptがいかに重要な言語かがわかりました。
ちなみに2つ紹介しましたが、基本的には2つ目のjsファイルを準備する方が後々のメンテナンスなどで修正がしやすくなるのでそちらを用いた方がいいみたいです。しょうがない場合などはあるのでしょうか、、、勉強していきたいと思います。
ややこい用語のかんたん解説（モジュール・メソッド・関数・パッケージ・ライブラリ）

# まとめ
人によって使われ方が違うな～としょっちゅう感じる曖昧な理解の用語たちを整理。
自分用備忘録。

| 用語 | 説明 |
| :---:  | :--- |
| 関数 | 引数を使用して何かしらの処理を実行し、結果を返すもののこと |
| メソッド | 「クラス」に所属している関数のこと |
| モジュール | 1つの.pyファイルのこと |
| パッケージ | モジュール群のこと<br>ただし、モジュール群の内に \_\_init__.py が存在しないものはパッケージとは呼ばない |
| ライブラリ | 定義が曖昧だが一般的には関数群のこと |
| フレームワーク | 目的に対して、最低限の処理が実装がされているもの* |

## *フレームワークの補足
自分の理解だが、請求書など事務系書類のテンプレートと置き換えるとわかりやすい。
名前や日付、請求項目など、内容は全て変えなければいけないが、最低限書くべき事項の枠が存在しているので、0から作る必要がなく、忘れてはいけないところをちゃんと補ってくれる。
これがプログラムになると、たとえばクライアントサーバーシステムならば、『API通信の処理』の枠などが存在する感じ。ざっくり。



## 関係
---
#### 　　パッケージ ⊃ モジュール ⊃ 関数/メソッド
---

「ライブラリ」はそもそもの定義が曖昧なので、人によって使い方が異なる言葉と理解。


以上
Laravelのルートモデル結合(ルートモデルバインディング)でid以外のカラムを使用する

## ルートモデル結合の基本的な使い方

### ルートモデル結合とは

モデルを取得する際に必要な定型処理のコードを減らすためのLaravelの機能です。

### 前提

以下の様なusersテーブルがあり、EloquentモデルのUserモデルを作成してあるものとします。
<dl>
<dt>users</dt>
<dd>id - integer</dd>
<dd>name - string</dd>
</dl>

### ルートモデル結合の利用方法

ルートモデル結合を利用してUserモデルをidカラムの値で取得したい場合は以下のようなコードになります。
URLのルートパラメータの値`{user}`とクロージャの引数の変数名`$user`を一致させ、引数の型にEloquentモデルの型を指定します。

```php:web.php
Route::get('users/{user}', function (User $user) {
    return $user; // idカラムの値で取得
});
```

そうすると、URLのパラメータの値と一致するidカラムの値を持ったUserモデルを簡単に取得出来るようになります。

例
/users/1と指定した場合は、idカラムの値が1のuserモデルを取得出来ます。


## id以外のカラムを使用したい場合


idではなくnameカラムの値でモデルを取得したい場合、コードが少し長くなってしまいます。


```php:web.php
Route::get('users/{name}', function (String $name) {
    $user = User::where('name', $name)->firstOrFail();
    return $user; // nameカラムの値で取得
});
```
ですが、Laravel7以降にはカラム名を変更できる便利な機能が用意されています。
`{変数名:カラム名}`といった形でURLのルートパラメータの値にカラム名を指定するだけです。


```php:web.php
Route::get('users/{user:name}', function (User $user) {
    return $user; // nameカラムの値で取得
});

Route::get('posts/{user}', function (User $user) {
    return $user; // カラム名を指定していないのでidカラムの値で取得
});
```

Laravel7以降のバージョンでは無い場合や、常にnameカラムの値で取得したい場合は、
UserモデルでgetRouteKeyNameメソッドを定義する方法もあります。


```php:User.php
public function getRouteKeyName()
{
    return 'name'; // カラム名
}
```

```php:web.php
Route::get('users/{user}', function (User $user) {
    return $user; // nameカラムの値で取得
});

Route::get('posts/{user}', function (User $user) {
    return $user; // nameカラムの値で取得
});
```

### 注意点

* URLのルートパラメータの値とクロージャ(アクションメソッド)の引数の変数名を一致させる事が必要です。

* nameカラムの値がユニークではない場合は、最初に見つかったUserモデルのみを取得します。
ユニークキー制約を設定することを忘れないようにしましょう。
ndarray空配列をあらかじめ用意してfor文で順番に値を入れていく方法

### やりたいこと
はじめに空の配列を宣言しておいて、for文を使って順番に値を入れていきたいときがある。

### リストの場合
```Python
l = []
for i in range(10):
    l.append(i) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
```
リストの場合はこのように書けば良いが、numpyではどう書けばいいか？
ググってもあんまり出てこなかったのでメモとして情報を残しておく。

### numpyの場合
```python
array = np.empty(0) 
for i in range(10):
    array = np.append(array, i)
    #array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
```

### 実行速度比較
```range(10000)```で実行速度を比較してみた。
##### list
```python
%%timeit
l = []
for i in range(10000):
    l.append(i)

#532 µs ± 16.2 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
```

##### numpy
```python
%%timeit
array = np.empty(0)
for i in range(10000):
    array = np.append(array, i)

#57.8 ms ± 2.08 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
```
空配列に順番に値を入れていくのであれば、listのほうが約100倍高速である。listで配列を追加していって、最後にndarrayに変換する場合は、

```python
%%timeit
l = []
for i in range(10000):
    l.append(i)
l_np = np.array(l)

#1.17 ms ± 29.7 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
```




予め配列のサイズが分かっているのであれば、```np.zeros()```を使用してはじめに要素を持った```ndarray```を用意するほうが高速に動作する。

```python
%%timeit
array = np.zeros(10000)
for i in range(10000):
    array[i] = i

#978 µs ± 31 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
```
【ServiceNow】Next Experienceのテーマ追加方法

# はじめに
みなさんこんにちは、三井情報株式会社です。

San Diegoで追加された機能である「Next Experience」について、以前[【ServiceNow】San Diegoリリース　Next Experience](https://qiita.com/ryohei-ishii/items/63a8588da26dcb03a55f)にて紹介させて頂きましたが、今回はその中のテーマにスポットを当ててご紹介致します。
Next Experienceのテーマでは、Next Experience以前のテーマ同様に開発者側で作成したカスタムテーマを利用することが可能です。
ただし、Next ExperienceのテーマとNext Experience以前のテーマは別物となっているため設定方法が異なります。
そのため、今回はカスタムで作成したテーマを利用できるようにするための必要な設定を説明していきます。

# カスタムテーマの設定方法
メニューの Now Experience Framework > Themes または sys_ux_theme.list で移動し、Polarisという名称のデフォルトテーマを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599975/eaeeb954-8e82-b43b-2217-efbfe9390eb4.png)

アプリケーションスコープを「sn-themes」に切り替え、事前にカスタムで作成したテーマをStyleに設定したレコードを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599975/470e5156-d668-83f2-b617-838a3dd4a93d.png)

Style以外の設定は以下となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599975/c02aec25-e30d-ab36-c0f6-a69687e14079.png)

Styleのレコードを追加した後、ユーザ設定のThemeを開くと今回追加したStyle名のテーマが表示されるので、それを選択するとカスタムテーマが適用されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599975/2d35c328-e86c-dbd9-9d31-77241d12056e.png)

以上がカスタムテーマを利用できるようにするための設定です。

余談ですが、「Next Experience」には標準で以下の「Dark」と呼ばれる一般的なダークテーマが用意されています。
ただし、デフォルトでは無効化されているのでこちらを有効にする手順を説明していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599975/fc8a5903-5075-426b-8c4b-3ab937b5b89d.png)

sys_properties.list に移動し、glide.ui.polaris.dark_themes_enabledをtrueにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599975/dc31f414-5d6b-0ce5-e934-bd14deb9d547.png)

ユーザ設定のThemeを開くとDarkという名称のテーマが存在するので、それを選択するとダークテーマに切り替えることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599975/77dad159-a929-4f16-6a34-63759575318e.png)

以上がカスタムテーマを利用できるようにするための設定です。

# おわりに
今回の記事にて、「Next Experience」へのカスタムテーマの追加方法について雰囲気をつかんでいただけましたら幸いです。
最後まで読んでいただき、ありがとうございました。

三井情報株式会社
ソリューション技術本部
ITマネジメント技術部
第一技術室
甲田善寛
量子回路を1つのユニタリー行列で表したい・・・手計算ではなく、パソコンで。

# 量子回路を1つのユニタリー行列で表したい

量子計算について学習するとき、「今の量子回路のユニタリー行列求めたいなー」って思う時があります。
もちろん、手計算で求められます。
でもqubitが多すぎて行列が大きくなった時は、思いのほか面倒です。
（あるいは単に面倒でやる気が出ない時）

そんな時に、パソコンにユニタリー行列を求めさせる方法について解説します。

# 1. Qiskitをインストールする
ネットを探したら方法はいくらでも見つかりますので、省略します。

# 2.Qiskit textbookをインストールする

以下のコマンドを実行します。
```
 pip install git+https://github.com/qiskit-community/qiskit-textbook.git#subdirectory=qiskit-textbook-src
``` 
# 3. 以下のプログラムを実行

```python
from qiskit import *
from qiskit_textbook.tools import array_to_latex

# （1）ユニタリー行列を求めたい量子回路を作る。（ここでは例として、簡単な回路を作ります）
qc = QuantumCircuit(2)
qc.h(0)
qc.x(1)

# あとはコピペでOKです。
# （2）実行して、unitaryを取得します。
backend = Aer.get_backend('unitary_simulator')
unitary = execute(qc,backend).result().get_unitary()

# （3）綺麗に表示します
array_to_latex(unitary, pretext="\\text{Circuit = }\n")
```

latexを使うので、Jupiter Notebook上で実行するのが良いと思います。
# 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252164/6e647101-9066-03cc-93dc-f1ef966656df.png)


# 具体例を紹介
1qubitに作用させる際、$HZH = X$となります。
1. Hゲートによって、基底をZ基底からX基底に変換
1. X基底においてZゲートはNOTの作用
1. Hゲートによって、基底をX基底からZ基底に変換

よって、$HZH=X$

確認してみましょう。
```python
from qiskit import *
from qiskit_textbook.tools import array_to_latex

# （1）ユニタリー行列を求めたい量子回路を作る。
qc = QuantumCircuit(1)
qc.h(0)
qc.z(0)
qc.h(0)


# あとはコピペでOKです。
# （2）実行して、unitaryを取得します。
backend = Aer.get_backend('unitary_simulator')
unitary = execute(qc,backend).result().get_unitary()

# （3）綺麗に表示します
array_to_latex(unitary, pretext="\\text{Circuit = }\n")

```
# 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252164/ad31277a-a8b6-1a53-dd11-98b24ce28132.png)

ちゃんと$X$ゲートになっていることがわかりますね。



 （この記事は https://qiskit.org/textbook/ja/ch-gates/multiple-qubits-entangled-states.html を参照）
Laravel9 + Postgres + Heroku Connect のプロジェクトでスキーマの指定を省略する

## 概要
Salesforce と連携したアプリケーションの開発をする際に、便利な設定を見つけたので記事にしました。
Salesforce のデータを Heroku Connect によって Heroku Postgres とデータ同期をすると `salesforce` というスキーマが作成されます。
今までは Eloquent モデルにテーブル名を指定する際に、下記のようにスキーマ名を入れていましたが、これを省略する方法を紹介します。

```php:App/Models/SalesforceTest.php
use Illuminate\Database\Eloquent\Model;
class SalesforceTest extends Model {
  protected $table = 'salesforce.test__c';
}
```


## 環境
- Laravel 9
- Heroku Postgres
- Heroku Connect

## 結論
https://devcenter.heroku.com/ja/articles/heroku-connect-database-tables#querying-mapped-tables

こちらの Heroku Connect のドキュメントにスキーマ名を省略する方法が載っていますが、別途SQLを発行する必要があります。
```
SET search_path TO salesforce,public;
```

この記事では Laravel の設定で上記と同じ状態にします。
結論から言いますと Laravel プロジェクトの設定ファイルの `config/database.php` 内にある `search_path` もしくは `schema` の項目に `salesforce` を追加すると完成です。

```php:config/database.php
'connections' => [
  'pgsql' => [
    'driver' => 'pgsql',
    'url' => env('DATABASE_URL'),
    'host' => env('DB_HOST', '127.0.0.1'),
    'port' => env('DB_PORT', '5432'),
    'database' => env('DB_DATABASE', 'forge'),
    'username' => env('DB_USERNAME', 'forge'),
    'password' => env('DB_PASSWORD', ''),
    'charset' => 'utf8',
    'prefix' => '',
    'prefix_indexes' => true,
-   'search_path' => 'public',
+   'search_path' => ['public', 'salesforce'],
    'sslmode' => 'prefer',
  ]
]
```

## 解説
ここからは Laravel 内での挙動を解説します。
Laravel が Postgres の DB にSQLを発行する際に `vendor/laravel/framework/src/Illuminate/Database/Connectors/PostgresConnector.php` の `configureSearchPath` 関数が実行されます。

```php:vendor/laravel/framework/src/Illuminate/Database/Connectors/PostgresConnector.php
/**
 * Set the "search_path" on the database connection.
 *
 * @param  \PDO  $connection
 * @param  array  $config
 * @return void
 */
protected function configureSearchPath($connection, $config)
{
  if (isset($config['search_path']) || isset($config['schema'])) {
    $searchPath = $this->quoteSearchPath(
      $this->parseSearchPath($config['search_path'] ?? $config['schema'])
    );  
    $connection->prepare("set search_path to {$searchPath}")->execute();
  }
}
```

この `$config` には `config/database.php` の `pgsql` の内容が入っています。
`search_path` がなければ `schema` が参照されるようになっているため、両方設定されている場合は `search_path` が優先されます。
また `quoteSearchPath` 関数と `parseSearchPath` 関数によって整形されるため、配列とカンマ区切りの設定に対応しています。

- `'search_path' => ['public', 'salesforce']`
- `'search_path' => 'public, salesforce'`

`$connection->prepare("set search_path to {$searchPath}")->execute();` により `search_path` が設定されます。

## 最後に
もし環境ごとにスキーマ名が変わる場合は、環境変数で制御するようにできます。

```environment:.env
DB_SCHEMA=stgpublic
DB_SCHEMA_SALESFORCE=stgsalesforce
```

```php:config/database.php
'connections' => [
  'pgsql' => [
    'search_path' => [env('DB_SCHEMA', 'public'), env('DB_SCHEMA_SALESFORCE', 'salesforce')],
  ]
]
```

同じ悩みを抱えている方の助けになれば嬉しいです。
私がコードを読んで解釈した内容ですので、もし間違っている箇所がありましたらご指摘いただけますと幸いです。
ROS melodicでcatkin_make中にtf2_ros::TransformListenerのエラーが出たときの対処法

# 問題
どうやらgeometry2関連のエラーらしい
# 解決法
geometry2のbranchが`noetic-devel`になっていたので
`git checkout melodic-devel`でbranchを切り替えた後、`catkin_make`を行ったら無事通った
シェルスクリプト書き方備忘録 (気が向いた時に更新し続ける予定)

自身のためのメモとしてShell Scriptの書き方をメモっておく。

# 好きなコマンドを永遠に繰り返し実行するためのScript
PollingのようにAPIをCallし続けるScriptを書きたくて作ったScriptのメモです。

```shell
#!/bin/sh
while true
do
    command="curl http://{target}"
    date
    eval $command
    sleep 5
done
```

この場合、

1. `date` コマンドを実行して現在時刻を出力し
2. `eval $command` でcommandの中身を実行し
3. 5秒間sleepして処理を繰り返す

という処理になります。

# JSONの配列でLoop処理
API Request BodyのJSONが多量にあって、それらをひたすらPOSTするってScriptを書く時に調べたのでメモ。

```shell
#!/bin/sh

json=$(cat << EOS
[
    {"field1":"value1","field2":"value2"},
    {"field1":"value3","field2":"value4"}
]
EOS
)

echo "$json"

len=$(echo $json | jq length)
for i in $( seq 0 $(($len - 1)) ); do
  row=$(echo $json | jq .[$i])
  echo "$row"

done
```

1. shellのヒアドキュメント( `cat << EOS **** EOS` )でjson変数に標準入力的な情報を設定
2. echoコマンドで$jsonを出力し、 `jq length` コマンドでパースして要素数を取得して `len` 変数に設定
3. `seq m n` でmからnの数字のリストを生成
4. `for i in ***; do done` でfor loop処理
5. echoコマンドで$jsonを出力し、 `jq .[$i]` コマンドでパースして要素番号が$iの要素を取得して `row` 変数に設定

echoコマンドの出力結果はこちら。

```
$json
[
    {"field1":"value1","field2":"value2"},
    {"field1":"value3","field2":"value4"}
]

$row
# 1回目のLoopの$row
{
  "field1": "value1",
  "field2": "value2"
}

# 2回目のLoopの$row
{
  "field1": "value3",
  "field2": "value4"
}
```

### Reference/参考文献
https://qiita.com/ryo0301/items/2ac9d11f355f1cf52ea5


また何かあればこの記事に追記していきたいと思います。
以上。
[Python]setup.pyで自作パッケージの配布

# はじめに
[前回](https://qiita.com/shuyaeer/items/2efa62de3622401c67fb)作成したPythonプログラムからGmailを送信するプログラムをパッケージ化し、グローバルに`import`できるようにします。

[github](https://github.com/shuyaeer/pymail)にリポジトリを作成したのでよろしければ御覧ください。

# パッケージ化

ディレクトリ内のトップレベルに`setup.py`を作成します。

```Python
from setuptools import setup

setup(
    name='pymail',
        version='1.0',
        description='Python Gmail Sender',
        author='shuyafukushima',
        author_email='',
        packages=['pymail'],
        install_requires=[],
        # install_requires=['wheel', 'bar', 'requests] 依存する外部ライブラリがあれば記述
    )

```

`setup.py`と同じ階層で `pip install .`を実行

```bash
$ pip install .
```

これでPythonのPathが通っているところからならどこでも`import pymail`ができるようになりました。


下記でインストールされたことが確認できます。

```bash
$ pip list | grep pymail
```

[README.md](https://github.com/shuyaeer/pymail/blob/master/README.md)を作成したので御覧ください。
# 参考
<https://docs.python.org/3/distutils/setupscript.html>
スマホでUbuntu 22.04を操作する【VNC】

### 設定を開く
![Screenshot from 2022-04-26 13-35-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/fd0e7b4b-0901-3c25-360b-9cc5905247f9.png)

### 共有からRemote Desktopを開く
![Screenshot from 2022-04-26 13-36-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/2cec6097-4e8d-33ea-cd0e-ef8231e3e49f.png)

### Enable Legacy VNC Protocol と Remote Control を有効にする
*VNC Address* をメモする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/15e6bb34-74d4-780b-db91-0dcd0e14cb48.png)

### スマホにVNC Viewerをインストール

Android

https://play.google.com/store/apps/details?id=com.realvnc.viewer.android

iOS

https://apps.apple.com/us/app/vnc-viewer/id352019548

### ＋ ボタンを押す
![Screenshot_20220426-133656.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/e7288205-7b1a-159d-93e3-87aadb67a13c.png)

### VNC Addressを入力して、CREATEボタンを押す
![Screenshot_20220426-133733.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/7170c370-3c5c-10e7-f025-e7d259412ea9.png)

### Picture qualityをHighにする
![Screenshot_20220426-133814.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/ae07e8f5-640d-7c5d-b18e-87a718244ceb.png)
![Screenshot_20220426-133833.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/6f3b1fbb-eb2a-fa39-2917-5aadcc5708df.png)
![Screenshot_20220426-133841.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/58c326f2-e6ac-ae0d-c800-42b66496a308.png)

### Connectを押す
![Screenshot_20220426-133841.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/88132870-44e7-ea20-7869-e7ea45fd69f7.png)

### Acceptする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/fc62a904-a281-32cb-6ddb-1c756b84bb7d.png)


### 接続完了🎉
![Screenshot_20220426-133941.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/53b9cf1e-471c-32f3-e6cc-58b452a2204c.png)

![ezgif-5-e71d87e62d.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/2c8bf693-57f8-df77-2c1f-087650585249.gif)
Lightning Experience での感謝バッジの利用


[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)
[まとめA～M](https://qiita.com/Keiji_otsubo/items/f3ddedee6793bf1576f8)

元の質問

[表彰制度を作りたいです](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000GzRJSSA3)

[WDC.: レコグニション - Apex を使用して感謝を贈る方法は?](https://help.salesforce.com/s/articleView?id=000332375&type=1)

これを見るとバッジ自体はWorkBadgeDefinitionというオブジェクトのようです。
バッジ名、説明、画像などのバッジの属性を表します。バッジ属性 (バッジ名など) は WorkBadgeDefinition オブジェクトから派生しているため、各 WorkBadge レコードには、WorkBadgeDefinition へのルックアップが必要です。

https://developer.salesforce.com/docs/atlas.ja-jp.object_reference.meta/object_reference/sforce_api_objects_workbadgedefinition.htm

この中には
ImageUrl 必須。これは、UI に表示されるバッジ画像です。ドキュメント ID または画像の URL を使用します。
というフィールドがあるので、このオブジェクトのこのフィールドから辿ることで画像を取得できると思います。

また実際にはWorkBadgeでバッジと送った人を管理している構成ではないかと思います。
https://developer.salesforce.com/docs/atlas.ja-jp.object_reference.meta/object_reference/sforce_api_objects_workbadge.htm

そこから考えるとWorkBadgeオブジェクトを検索してWorkBadgeDefinitionのImageUrl を取得すれば画像が分かり、WorkBadgeのGiverIdを取得すれば感謝バッチを贈与したユーザのIdが分かると思います。

もし、私が実装するならAuraコンポーネントしか分からないので、
ユーザIdからこの２つのオブジェクトを検索してバッチの画像を表示するようなコンポーネントを作って、ユーザオブジェクトの画面に埋め込むようなことをすると思います。

やっぱり探せばあった。
[LIGHTNINGEXPERIENCEの感謝バッジ](https://salesforcediaries.com/2019/03/06/thanks-and-badges-in-lightning-experience/)


# 関連しそうな情報

+ [バッジアクセスレコードをワークベンチ経由で一括付与する方法](https://help.salesforce.com/s/articleView?id=000333883&type=1)
+ [soql - cross object - workbadge and workbadgedefinition](https://salesforce.stackexchange.com/questions/100953/soql-cross-object-workbadge-and-workbadgedefinition)
PydicomでDICOM画像を読み込めない！の解決策。圧縮されたDICOM画像の対処法。

# 問題
とある研究で、DICOMを使用している。いつも通り、Pydicomを使用してDICOM画像を読み込もうとしたらエラー。
```
RuntimeError: The following handlers are available to decode the pixel data however they are missing required dependencies: GDCM (req. GDCM), JPEG-LS (req. CharPyLS), pylibjpeg (req. )
```
初めて見るエラー。同じ施設内のデータなのに何故読み込めるデータと読み込めないデータが？？
# 処置
いつも通り、エラーをそのままコピペしてググった。
以下のサイトが出てきて、参考にした。
①　https://stackoverflow.com/questions/54657768/pydicom-cant-read-pixel-data-and-needs-gdcm-or-pillow
②　https://pydicom.github.io/pydicom/stable/old/image_data_handlers.html
上記サイトにより、いつも使用しているDICOMファイルの画像はローデータであり、圧縮されていないのでは？？と推測した。そして、今回のファイルの画像は、施設の何らかの画像解析ソフトを介して出力されたファイルであり、圧縮されていたと考えた。
圧縮されたDICOMの```pixel_array```は、②により圧縮状態から解凍するための以下のパッケージが必要だそう。
```
・GDCM
・Pillow
・jpeg_ls
・pylibjpeg
```
ということで、上記パッケージを```pip install```を行い、再実行すると、無事問題解決！！
# まとめ
今回のケースでは、よくわからない不思議な現象で困惑していましたが、冷静にエラーに書いてある通りに対処すれば解決しました！！
何かの参考になれば幸いです。
空白か先頭か（あるいは空白か文末）という正規表現

正規表現で少し詰まったので、記事としてアウトプットしておく。

Ruby 2.7.6で検証しています。

## やりたいこと

(空白か先頭)特定の文字列(空白か文末)という正規表現を書きたい。改行は入らないので考慮を今回はせず1行の文字列で考えます。
この正規表現を特定の文字列strに対して、`reg(str)`としましょう。

具体的には

```ruby
> ' 大阪市'.match?(`reg('大阪市')`)
=> true

> ' 大阪市'.match?(`reg('大阪')`)
=> false

> ' 大阪 市'.match?(`reg('大阪')`)
=> true
```

のようなイメージ。純粋にinclude?関数を使うと、後者はtrueになってしまうので別途正規表現を作る必要が出てきました。

## こんな正規表現を書いた

```ruby
> ' 大阪市'.match?(/[\s|\A]#{'大阪市'}[\s|\z]/)
=> false
> ' 大阪市'.match?(/[\s|\A]#{'大阪'}[\s|\z]/)
=> false
```

通常の文字(`a`とか`あ`とか)であれば`[]`を使えばいいのですが、`[]`は文字クラスであり、`\A`はアンカー(文字ではない。位置にマッチする表現)ので動きません。

## グループを使おう

今回やりたい正規表現は下記の通りでした。

```ruby
> ' 大阪市'.match?(/(\A|\s)#{'大阪市'}(\s|\z)/)
=> true
> ' 大阪市'.match?(/(\A|\s)#{'大阪'}(\s|\z)/)
=> false
```

空白と先頭のグループにマッチするかを判定、直後に特定の文字列があるかを確認して、更にその直後に空白と文末のグループにマッチするかを見る、という表現になりました。


## もう一歩踏み込んで

グループに?:をつけることで、キャプチャせずにグループ化を行うことができ、若干早くなるみたいです。

```ruby
> ' 大阪市'.match?(/(?:\A|\s)#{'大阪市'}(?:\s|\z)/)
=> true
> ' 大阪市'.match?(/(?:\A|\s)#{'大阪'}(?:\s|\z)/)
=> false
```

更に、上記だと全角スペースや非ASCIIの空白文字の対応が漏れてしまっているので、`\s`を`[[:space:]]`にして

```ruby
> '　大阪市'.match?(/(?:\A|[[:space:]])#{'大阪市'}(?:[[:space:]]|\z)/)
=> true
> '　大阪市'.match?(/(?:\A|[[:space:]])#{'大阪'}(?:[[:space:]]|\z)/)
=> false
```

とするのが良さそうです(@scivolaさんありがとうございました！)。

## REF

[正規表現 (Ruby 3.1 リファレンスマニュアル)](https://docs.ruby-lang.org/ja/latest/doc/spec=2fregexp.html)
【Laravel】Requestクラスのインスタンスにリクエストヘッダーを追加する

確認したバージョン: Laravel 6.20

# やりかた
`$request->header`の`set`メソッドで実現できます。
```php:sample.php:
<?php
use Illuminate\Http\Request;

// リクエスト生成
$request = new Request;
// Request Header追加(例として「Authorization: Bearer test_token」を追加します)
$request->headers->set('Authorization', 'Bearer ' . 'test_token'); 

dd($request); //出力
```

結果
```bash
Illuminate\Http\Request^ {#676
  #json: null
  
//省略//

  +headers: Symfony\Component\HttpFoundation\HeaderBag^ {#123
    #headers: array:1 [
      "authorization" => array:1 [
        0 => "Bearer test_token"
      ]
    ]
    #cacheControl: []
  }

//省略//

}
```
`headers`プロパティの中に新たに`authorization`が追加されました。

# 参考
https://qiita.com/kd9951/items/9b6ef7d2c505522d873b

https://readouble.com/laravel/8.x/ja/requests.html
ゾッとする話　初めてのShopify構築案件で闇をみた


# ストーリー
Shopifyの構築に興味があり、自分でサンプルのサイトを作成していて、ある程度理解したので、そろそろ案件獲得したいなぁと思い営業。
初心者なので低価格でしますよー多少のコード編集は可能ですよーと提案することで無事案件を獲得できたのだが、、、。

初めての受注に戸惑い、どうしたらいいかわからず、流れに身を任せる
見積もりもなく、4万でお願いしますとのこと
初めてなので仕方ないかと思い何も確認せず了承
デザインを頂きこのデザインで構築お願いしますとの事
デザイン確認
あれっテーマに沿ったデザインじゃなくて完全にオリジナルデザインやん、、、、
あれっ多少のコード編集でのデザインの変更は可能ですって言ったけど完全オリジナルやん、、、
でもやったことないからやればできるかも？？と思い挑戦してみる
一つのセクション作るのに一日かかる
デザインを確認　オリジナルのセクション30個程、、、、
これ4万程の仕事やぞ、、、
（6時間×30セクション）＋(商品登録等20時間)＝200時間
　4万÷200時間=時給200円
あぁ、、、絶望


## 気をつけよう
　・デザインが元々ある場合、既存のテーマでどこまで対応できるか把握しておく
　　対応できない部分は何セクションあるか確認する
　・初心者はデザインが用意されていない場合、
　　既存テーマでなるべく、対応し本当に必要な部分のみコード編集でセクションを作成しよう
　・無理なことは事前に相談、交渉しよう

## 自分なりの構築の工数の出し方
　・ヘッダー、フッターの設定
　　　既存テーマかオリジナルか
　・ページ数、セクション数
　　　既存テーマかオリジナルかで数える個数変える
　・商品登録の数
　・設定項目
　　　送料や規約など
　・テスト、修正
Vue.jsの不思議【emit】【複数の引数】

<h1>emitの基本</h1>

子→親へデータを渡す場合、emitを使用する

<h3>emitの書き方</h3>

```javascript
this.$emit("親で実行する関数名", "引数1","引数2","引数3");
```

引数は何個でも取れる

```App.vue
<template>
  <div>
    <child @parent="test" />
  </div>
</template>

<script>
import Child from "./components/Child.vue";

export default {
  components: {
    Child,
  },
  methods: {
    test(arg) {
      console.log("test", arg);
    },
  },
};
</script>

//コンソール
test 
テストメッセージ 
```

```Child.vue
<template>
  <div>
    <button @click="click">親にメッセージを渡す</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      newMessage: "テストメッセージ",
    };
  },
  methods: {
    click() {
      this.$emit("parent", newMessage);
    },
  },
};
</script>
```

これでOK

親をこう書き換えても同じ動作をする

```App.vue
<child @parent="test" />
```

```App.vue
<child @parent="test($event)" />
```

プロパティに直接代入することも可能である
```App.vue
<template>
  <div>
    {{ message }}
    <child @parent="message = $event" />
  </div>
</template>

<script>
import Child from "./components/Child.vue";

export default {
  components: {
    Child,
  },

  data() {
    return {
      message: "",
    };
  },
};
</script>
```

要するに

```vue
<child @parent="ここ！！！" />
```

ここ！！！にはjavaScriptが書けるのである

<h1>親側で条件分岐する</h1>

子からのイベントで親の関数を条件付きで実行したい場合

↓だと関数が実行されない

```App.vue
<template>
  <div>
    <child @parent="flag ? test1 : test2" />
  </div>
</template>

<script>
import Child from "./components/Child.vue";

export default {
  components: {
    Child,
  },
  computed: {
    flag() {
      return false;
    },
  },
  methods: {
    test1(arg) {
      console.log("true",arg);
    },
    test2(arg) {
      console.log("false",arg);
    },
  },
};
</script>
```

↓で正しく実行される

```App.vue
<template>
  <div>
    <child @parent="flag ? test1($event) : test2($event)" />
  </div>
</template>

<script>
  //上と同じため省略
</script>

//コンソール
false 
テストメッセージ 
```

おそらく、
```vue
@parent
```
が実行されたときに

```vue
<child @parent="flag ? test1 : test2" />
```
true,falseの判定だけ実行し、実際の関数は実行されないのであろう


```vue
<child @parent="flag ? test1($event) : test2($event)" />
```

なので関数を実行する()が必要である

```vue
<child @parent="test1" />
```

関数のみの場合、関数を実行してくれる


<h3>emitの第二引数</h3>

しかしこの書き方だと、emitに第二引数があった場合、どうするのだろうか？
```vue
<child @parent="flag ? test1($event) : test2($event)" />
```

私は第二引数を使わずに引数が２つあったらオブジェクトにして渡していたが、
もっといいやり方があるのかもしれない

vue3だと何か変化があったりするのかもしれない

---環境---
mac
vue2.6.11
node 最新LTS
Notionのアイコン画像を正方形に編集するWEBアプリケーションを作った

# はじめに： 解決したいこと

みなさん、[Notion](https://www.notion.so/ja-jp/product) 使ってますか？
Notionでページを作成していたところ、アイコン画像を設定するときに困ったことが起きました。
それは、長方形の画像をアイコンとしてアップロードすると、下の写真のように画像が見切れてしまうということです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/873482/b0d6d211-6411-9d86-1661-8879b668ab55.png" width="600px">

この記事では、[Streamlit](https://www.streamlit.io/) を使ってNotionのアイコン用に画像を正方形に加工してくれるWEBアプリケーションを作成したので紹介します。
作成したWEBアプリは [こちら](https://share.streamlit.io/masachika-kamada/notion-icon-reshape/main.py) から使用できます。
作成したプログラムは [こちら](https://github.com/masachika-kamada/streamlit_qiita)。
Streamlitの基本的な使い方については、[この記事](https://qiita.com/_m_a_s_a_/items/d9bcf23c93d6caf02b60) で紹介しています。

# ソリューション

- OpenCVを使って長方形の画像を正方形に加工
- ( 長辺と短辺の差の半分の長さ ) × ( 長辺 ) の長方形を両側から結合
- Streamlitを使って画像をアップロードすると上記の処理を行ってくれるWEBアプリケーションを作成

# 実装

コード全体は [こちら](https://github.com/masachika-kamada/notion-icon-reshape/blob/master/main.py) から。

まず画像をアップロードして、それを読み込みます。

```python
st.markdown('# Notion Icon Maker')
file = st.file_uploader('画像をアップロードしてください', type=['jpg', 'jpeg', 'png'])
if file:
    st.markdown(f'{file.name} をアップロードしました')
    img = Image.open(file)
    st.image(img)
```

次に画像を正方形に加工します。
アップロードした画像は Pillow の形式で読み込まれているため、画像加工の前に OpenCV 形式に変換します。
また、正方形にするために付け足した部分は透過させる必要があります。
そこで、画像のチャンネル BGRA のうち、Aの値を0にすることで透過画像を作成することができます。
作成した透過画像の中央に、元画像を配置して完成です。

```python
def make_square(image):
    h, w = image.shape[:2]
    a = max(h, w)
    blank = np.full((a, a, 4), 0, dtype=np.uint8)
    blank[int(a / 2 - h / 2):int(a / 2 - h / 2) + h,
          int(a / 2 - w / 2):int(a / 2 - w / 2) + w] = image
    return blank

cv_img = pil2cv(img)
dst = make_square(cv_img)
```

# 最後に

作成したWEBアプリケーションを使うことで、下のようにいい感じにアイコンを設定できました。
Notion のアイコン設定で困ったら使ってみてください。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/873482/238617a8-0b23-8a4e-9082-e9a8e11fbff9.png" width="600px">
【Rails】Model名とControllerのModule名が重複してNoMethodErrorが発生した時の対応

備忘を兼ねて

## Moduleとモデル名が重複するとNoMethodErrorになる

ファイル構成

```
app
├── controllers
│   └──user
│        └── hoges_controller.rb
└── models
    └── users.rb
```

```rb:hoges_controller.rb
module User
    class HogesController < User::ApplicationController
        def index
            User.where(id: ids)
        end
        ## その他メソッド省略
    end
end
```

```:エラー内容
NoMethodError in User::HogesController#index
undefined method `where' for User::Module
```

## エラーの原因

モデル名とコントローラー側で定義したモデュール名が重複しており、`User`を呼び出すとModule側が優先されてしまう。


## 対策
モデルを呼び出したい時は`::`を頭につけるだけ。

```rb:hoges_controller.rb
            ::User.where(id: ids)
```