OmniAICreator/Qiita-1.07M huggingface dataset:
【Python】seleniumで親要素/子要素を取得する

## 初めに
Seleniumを使っていると、Webサイトによっては同名のクラス名やidなどが存在して思うようにデータが取れない場合があります。  
FullXPATHで指定することもできますが、少しでもWebの要素が変わると全てのXPATHを書き直す必要が出てくるかもしれません。  

ある要素を軸に階層移動出来れば楽になりそうだと思ったので、色々と調べてまとめました。  

## バージョン
- selenium: v4.7.2

## 要素の取得  

単一要素であれば`find_element`、複数の要素であれば`find_elements`で取得できます。
取得した要素は、`WebElement`型になります(複数の場合は`list[WebElement]`)。
```python
# 単一要素
elm = driber.find_element(By.CLASS_NAME, "class_name")
# 複数要素
plants = driver.find_elements(By.TAG_NAME, "li")
elm = plants[0]
```
この`elm`から階層移動することが出来ます。  

## 親要素の取得
現在の`WebElement`が`elm`という名前で、そこから1階層だけ上に行きたい場合は、下記のように書きます
```python
elm.find_element(By.XPATH, "..")
```
2階層上に行きたい場合は、
```python
elm.find_element(By.XPATH, "../..")
```
と書くだけです。

因みに`WebElement`は`parent`を持っていますが、これは親階層ではなく、その要素が属する`WebDriver`インスタンスへの内部参照を返します([参照](https://kurozumi.github.io/selenium-python/api.html#selenium.webdriver.remote.webelement.WebElement.parent))

## 子要素の取得
### XPATH以外
これは[ドキュメント](https://www.selenium.dev/ja/documentation/webdriver/elements/finders/#dom%E3%81%AE%E3%82%B5%E3%83%96%E3%82%BB%E3%83%83%E3%83%88%E3%81%AE%E8%A9%95%E4%BE%A1)を読めば分かります。軽く触れておきましょう。
HTMLが下記の構成だと仮定します。
```HTML
<ol id="vegetables">
 <li class="potatoes">…
 <li class="onions">…
 <li class="tomatoes"><span>Tomato is a Vegetable</span>…
</ol>
<ul id="fruits">
  <li class="bananas">…
  <li class="apples">…
  <li class="tomatoes"><span>Tomato is a Fruit</span>…
</ul>
```
そして、`<ul id="fruits">`の子要素である`<li class="tomatoes">`を取得したい場合は下記のように書きます。
```python
fruits = driver.find_element(By.ID, "fruits")
tomatoes = fruits.find_element(By.CLASS_NAME,"tomatoes")
```
`WebElement`属性の`find_element`は、その属性の子要素を探索してくれます。
→ 上記のように検索しても、子要素にはない`vegetables`の`tomatoes`は取得されない。 

### XPATH
XPATHも基本的には同じですが、XPATHの中身が少し異なります。
今回はHTMLが下記の構成だと仮定します。
```HTML
<ul id="foods">
  <li class="fruits" title="bananas">…
  <li class="fruits" title="apples">…
  <li class="fruits" title="tomatoes"><span>Tomato is a Fruit</span>…
</ul>
<ul id="fruits">
  <li class="fruits" title="bananas">…
  <li class="fruits" title="apples">…
  <li class="fruits" title="tomatoes"><span>Tomato is a Fruit</span>…
</ul>
```
`<ul id="fruits">`の方の`<li class="fruits" title="bananas">`を取得してみましょう。

まずは`fruits`の要素にアクセスして、そこから`title=bananas`を指定して取得する方法を考えてみます。

seleniumでは、`By.TITLE`がないのでXPATHで書く必要が出てきます。
→ `//li[@title="bananas"]`
これを組み合わせると下記のように書けます。  
```python
fruits = driver.find_element(By.ID, "fruits")
bananas = fruits.find_element(By.XPATH, "//li[@title='bananas']")
```
しかし、このように書いても**両方(foods, fruits)のbananasが取得されてしまいます。**
これはXPATHの`//`に原因があり、この`//`はルートから検索されてしまいます。
`WebElement`で現在いる階層を指定しても、`XPATH`を書き間違えると思うような動作が出来ないので注意が必要です。

子の要素をXPATHで取得する際は、XPATHの前に`.`を書いてあげましょう。
```python
bananas = fruits.find_element(By.XPATH, ".//li[@title='bananas']")
```

これで`fruits`の`tomatoes`要素だけが取得出来ました。  

## 終わりに
`XPATH`を扱うのであれば、`XPATH`の記法を学びましょう(自戒)  

## 参考
https://www.selenium.dev/ja/documentation/webdriver/elements/finders/

https://qiita.com/rllllho/items/cb1187cec0fb17fc650a

https://gogodiet.net/z/xml/7.htm
Nest.jsについて

Nest.js
- Typescirptと相性が良い
- Expressをコアにして作られている
- Expressよりも機能が多い
- Angularにインスパイアされている


- 型の恩恵を受けることができる
- テストフレームワークが標準で用意されている
- 拡張性が高い

Nexts CLI
- Nestコマンドラインインターフェイス
- 新規コントローラー作成
```
$nest g controller コントローラー名
React + TypeScriptで使えるネットワークグラフ系ライブラリ3つ + α

ノードとエッジで表現されるネットワークグラフを描画できるReact + TypeScriptな環境で使えるライブラリをいくつか調べたのでそのまとめです。

# まとめ

| ライブラリ名　| オススメ度　| まとめ記事　|
| :-- | :-- | :-- |
| Cytoscape.js | ◎ |[ReactにCytoscape.jsでネットワークグラフを書いてみた](https://zenn.dev/k8shiro/articles/sample-cytoscapejs) |
| React Flow | ○ | [ReactにReact Flowでネットワークグラフを書いてみた](https://zenn.dev/k8shiro/articles/sample-react-flow) |
| Sigma.js | △ | [Reactにsigma.jsでネットワークグラフを書いてみた](https://zenn.dev/k8shiro/articles/sample-sigma-js) |
| vis.js | × | TypeScript未対応で調査中止 |


調査した各ライブラリについては別途、動かして見たときの内容を記事にまとめたのでそちらも参照ください。

上記の中でvis.jsはreact-graph-visを入れてReact上で動かして見たのですが、TypeScriptに対応していないようで@typesがなく自分で型定義をしてあげる必要があったので途中で調査中止しました。

上記の中ではCytoscape.jsを使っておけば困らないのではないかと思います。React Flowは一部有料、Sigma.jsはスマホから試した時に一部touch eventの動作がうまく扱えないものがありました。ただ、React Flowはノードの形や内部に色々書き込めるような作りになっているなど、デザイン面の要件も合わせてどれを選択するかは変わってくるのかと思います。
Blenderでモーションデータの特定のボーンを一括でリネーム・削除するスクリプト

# 内容
モーションデータの一部（補助骨や指の関節など）が不要の場合、簡易化したデータにする必要がありますが、その対応方法の備忘録です。
一部名前を変更したいボーンがあったので、その部分の名前の変更も行っています。

# Blender Pythonでのボーンの種類
### Bone
Objectモードのボーン。**Read Only**なので、名前の変更やボーンの追加、削除ができません。
### EditBone
Editモードのボーン。**名前の変更やボーンの追加、削除ができます**が、フレームごとのデータ編集はできません。
### PoseBone
Poseモードのボーン。**フレームごとのデータ編集**ができます。

<br>
<br>
<br>

今回はフレームデータを編集しないので、**EditBone**を使用します。

# コード例

<br>

```python:rename.py
import bpy
import os

src_to_tgt = {"Upper":"Up", "Lower":"Bottom"} # リネーム用の対応関係例
bones_to_remove = ["Helper:Cloth1", "Helper:Cloth2", "Helper:Cloth3", "Helper:Cloth4", "Helper:Cloth5"] # 削除用の骨の例

def init_scene():
    if bpy.context:
        scene = bpy.context.scene
        for obj in scene.objects:
            bpy.data.objects.remove(obj, do_unlink=True)
        
def convert_bvh(input_path, output_path):
    bpy.ops.import_anim.bvh(filepath=input_path)
    bpy.ops.object.select_by_type(extend=False, type='ARMATURE')

    arm_data = bpy.context.object.data
    bpy.ops.object.mode_set(mode='EDIT')
    for bone in arm_data.edit_bones:
        if bone.name[:5] in src_to_tgt.keys():
            bone.name = src_to_tgt[bone.name[:5]] + bone.name[5:] # リネーム
        
        if bone.name in bones_to_remove:
            arm_data.edit_bones.remove(bone) # 削除
        
    bpy.ops.object.mode_set(mode='OBJECT') # OBJECTモードにして編集したEditBoneをBoneに適用
    bpy.ops.export_anim.bvh(filepath=output_path)

if __name__ ==  '__main__':
    input_dir = "元のBVH群を格納するフォルダへのパス"
    output_dir = "出力するBVH群を格納するフォルダへのパス"
    os.makedirs(out_dir, exist_ok=True)
    for input_file in os.listdir(in_dir):
        init_scene()
        input_path = input_dir + input_file
        output_path = output_dir + input_file[:-4] + "_edited.bvh"
        convert_bvh(input_path, output_path)
```

<br>
 

- 注意点としては BlenderのBVH出力関数がBoneを参照するため、
編集したモーションをエクスポートする前にObjectモードに変更する必要があります。
これによりBoneがEditBoneのデータに更新されます。
kerasのconcatenateレイヤーを使い，画像と他の引数をCNNにぶちこむとき

## はじめに
`numpy`の文法を，当たり前に書ければつまずくことは無かったと思う．自分向けの備忘録として書きます．

**やりたいこと**
研究にて，回帰予測モデルを構築したい

**できなかったこと**
CNNアーキテクチャに入力変数を入れるとき，思うように型変換ができなかった．

エラー文は以下
```
Failed to convert a NumPy array to a Tensor (Unsupported object type numpy.ndarray)
```

### 期待される入力サイズ
1. 画像（300×300×3）
1. 他の変数（n）

ただし，n は自然数．
データ数が1000で，他の変数の数が7とすると，とすると，(1000,300,300,3)，他の変数は(1000,7),ということになる．

他の変数って何，というと，例えば
画像の他に，圧縮強度や空隙率，透水係数，etc. からP波速度を推定するといったみたいな．そんな論文がありました．

### データの中身
csvファイルを`DataFrame`にて読み込み，`train_test_split`を用いてデータを分割する．

|  path  |  Volume  | Strength |
| ---- | ---- | --- |
|  /data/sample1.png  |  302.123  | 50.21 |
|  /data/sample2.png  |  212.121  | 32.12 |

みたいな感じ．もちろん架空のデータであり，4列目以降もある．
pathだけは`kears.preprocessing.load_img`にて読み込む．

## 解決パート
### concatenateを使ったときの文法は
`df`として格納した上のデータ（1列目は`load_img`にて読んだ画像，2列目は`Volume`...）を，kerasが要求する`ndarray`にする．

```python:画像だけ入れる
model.fit(x=x_train, y=y_train)
```
を，
```python:画像とは別に他の変数x_train2を入れる
model.fit(x=[x_train1, x_train2],y=y_train)
```
みたいにすれば良いらしい．
今回は，`x_train1`が`x_train["Image"]`，`x_train2`が`x_train[["Volume","Strength"]]`となっているわけだ．

### どうやって入れるか
紆余曲折会ったけど，最終的にこうやった
```python
history = model.fit(
    # x_train, y_train, # 画像だけが説明変数ならば
    [
        np.stack(x_train[["Image"]].values.flatten(), axis=0).astype(np.float32),
     x_train[["Volume","Strength"]].values.astype(np.float32)
     ],
    y_train,
                    epochs=64,
                    validation_split=0.2,
                    )
```

## どうやって抜け出したか
chatGPTです．ずっと相談していました．本当にありがとう．
自分一人では，きっと処理できなかった．`numpy`の勉強不足のツケを払わされました．![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530290/2ed696d5-e7e6-8a55-2434-0cc4352feb55.png)
PostgreSQLのOperatorにCloudNativePGを選択した経緯

![スクリーンショット 2023-02-02 163645.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109639/dddf6486-661b-20f4-ae98-962310db0304.png)


## 発端
- 新しく作るK8sベースのWebアプリのDBに、数年前使っていたPostgreSQLのKubernetes Operatorである[Crunchy Data](https://www.crunchydata.com/)のPGOを使おうと思った
- しかし、Crunchy DataのPGOを改めて調べてみると、ソース自体はオープンソースだが、使っているコンテナイメージがオープンソースではなく実質商用利用できないらしいことがわかった[参考1](https://www.kaitoy.xyz/2022/09/10/crunchy-data-pgo-is-not-oss/)[参考2](https://news.ycombinator.com/item?id=31882256)
- そこでオープンソースのPostgreSQL向けOperatorを調査して使うべきものを選定した
- ざっくりした選定基準は、Cloud Providerにバックアップできるか、カスタマイズ項目が多いか、カスタマイズしやすいか、将来的に使い続けられそうか等

## 俯瞰調査
- 下記のオープンソースのPostgreSQL向けOperatorについて調査
    - CrunchyData/postgres-operator
    - cloudnative-pg/cloudnative-pg
    - zalando/postgres-operator
    - ongres/stackgres
    - percona/percona-postgresql-operator
    - sorintlab/stolon
    - (kubedb/docs)
- 上記のプロジェクトの概要（カスタマイズ性やプロジェクトの盛り上がり等）を調査したところ、機能面で優れるCrunchyDataのPGOをforkして作られたPerconaのPostgres Operatorと、CNCFプロジェクト（Sandbox）にリクエストしたCloudNativePGが良さそうに思えた
- 比較調査の詳細はこちら：[**KubernetesのPostgreSQL向けOperator比較**](https://lethediana.sakura.ne.jp/tech/archives/overview-ja/1973/)
- [CNCFについて](https://lethediana.sakura.ne.jp/tech/archives/summary-ja/1884/)

## percona-postgresql-operatorとcloudnative-pgをローカルで試す
- WSL2のkind上にそれぞれのOperatorをデプロイしてみた
### percona-postgresql-operator
- v2.0.0が最新バージョンとの記載があったが、Helmでもソースからでもエラーが出てデプロイできなかった（デフォルト設定でデプロイできるかのみを試した）ので、v1.3.0でテスト（v1.3.0はCrunchy Data PGOの4.7相当）
- アプリから使うときはpgBounderというServiceにアクセスすることでDBを利用する
- 手順と上記の話の詳細：[Percona Operator for PostgreSQLを動かしてみる](https://lethediana.sakura.ne.jp/tech/archives/steps-ja/2014/)

### cloudnative-pg
- 通常は、Cluster名の後に-r、-ro、-rwがsuffixとしてついたServiceにアクセスすることで、DBを利用する（読み書きしたければ、-rwのServiceを使う）
- 手順と上記の話の詳細：[CloudNativePGを動かしてみる](https://lethediana.sakura.ne.jp/tech/archives/steps-ja/2004/)

## ここまで調べての所感＋議論したこと
- Crunchy DataのPostgreSQL Operatorの知見を利用できるCrunchy DataのPGOをforkしたPerconaのOperatorは機能的に非常に魅力的
- ただし、Crunchy Dataの後追いになる
- CloudNativePGは、CNCFにリクエストしたのもあり、将来性にも強力なオープンソースコミュニティになりそう（注目度が高いのか、GithubのStar数の伸びがPerconaを上回る）
- PerconaのOperatorが将来的にオープンソースでなくなることはないと思うが、なんともいえないところ
- CLoudNativePGのfull-exampleのyamlと、PerconaのOperatorのOptionページを見ると、PerconaのOperatorの方が圧倒的に設定項目数が多いため、PerconaのOperatorの方がカスタマイズ性は高そう
- ドキュメントはCloudNativePGの方がわかりやすいのでアーキテクチャをイメージしやすい（PerconaのOperatorのドキュメントはところどころCrunchy Dataへのリンクになっているところがある）
（追記する可能性あり）

## 結論
- CNCFの認定ステージを注視しつつ、CloudNativePGで進める
rubyXLのconvenience_methods メソッド一覧

公式の方でまとめられているものを書き出しています
https://github.com/weshatheleopard/rubyXL/tree/master/lib/rubyXL

####  rubyXL/convenience_methods/cell
- change_contents
- remove_formula
- get_border
- get_border_color
- change_horizontal_alignment
- change_vertical_alignment
- change_text_wrap
- change_shrink_to_fit
- change_text_rotation
- change_text_indent
- change_border
- change_border_color
- is_italicized
- is_bolded
- is_underlined
- is_struckthrough
- font_name
- font_size
- font_color
- fill_color
- horizontal_alignment
- vertical_alignment
- text_wrap
- text_rotation
- text_indent
- set_number_format
- change_fill
- change_font_name
- change_font_size
- change_font_color
- change_font_italics
- change_font_bold
- change_font_underline
- change_font_strikethrough
- update_font_references
- font_switch
- add_hyperlink
- add_shared_string

####  rubyXL/convenience_methods/color
- get_rgb
- to_hls
- to_rgb
- to_s
- set_color
- self.parse
- apply_tint


#### rubyXL/convenience_methods/font
- is_italic
- is_bold
- is_underlined
- is_strikethrough
- get_name
- get_size
- get_rgb_color
- set_italic
- set_bold
- set_underline
- set_strikethrough
- set_name
- set_size
- set_rgb_color

####  rubyXL/convenience_methods/workbook

- each
- cell_xfs
- fonts
- fills
- borders
- get_fill_color
- register_new_fill
- register_new_font
- register_new_xf
- modify_alignment
- modify_fill
- modify_border
- modify_border_color
- password_hash
- define_new_name
- get_defined_name
- title

####  rubyXL/convenience_methods/worksheet

- insert_cell
- delete_cell
- insert_row
- delete_row
- insert_column
- delete_column
- get_row_style
- get_row_fill
- get_row_font_name
- get_row_font_size
- get_row_font_color
- is_row_italicized
- is_row_bolded
- is_row_underlined
- is_row_struckthrough
- get_row_height
- get_row_border
- get_row_border_color
- row_font
- get_row_alignment
- get_cols_style_index
- get_column_font_name
- get_column_font_size
- get_column_font_color
- is_column_italicized
- is_column_bolded
- is_column_underlined
- is_column_struckthrough
- get_column_width_raw
- get_column_width
- change_column_width_raw
- change_column_width
- get_col_style
- get_column_fill
- change_column_fill
- get_column_border
- get_column_border_color
- column_font
- get_column_alignment
- change_row_horizontal_alignment
- change_row_vertical_alignment
- change_row_border
- change_row_border_color
- change_row_fill
- change_row_font
- change_row_font_name
- change_row_font_size
- change_row_font_color
- change_row_italics
- change_row_bold
- change_row_underline
- change_row_strikethrough
- change_row_height
- change_column_font
- change_column_font_name
- change_column_font_size
- change_column_font_color
- change_column_italics
- change_column_bold
- change_column_underline
- change_column_strikethrough
- change_column_horizontal_alignment
- change_column_vertical_alignment
- change_column_border
- change_column_border_color
- change_row_alignment
- change_column_alignment
- merge_cells
- add_validation_list
Mac（zsh）でdateコマンドで任意日付のUnixTime（エポック秒）を操作する

## 指定した時刻のUNIX時間（エポック秒）を出力

```zsh
$ date -jf "%Y/%m/%d %H:%M:%S" "2023/02/14 23:59:59" +%s
1676386799
```

## 指定したUNIX時間（エポック秒）をフォーマットして出力

```zsh
$ date -jr 1676386799 +"%Y/%m/%d %H:%M:%S"
2023/02/14 23:59:59
```
面白いと思ったAI紹介

https://theresanaiforthat.com/

このサイトにはさまざまな用途のAIがリスト化されています。
その中でも僕が個人的に面白いなと思ったサービスを紹介します。

### ツイート自動作成
自分のツイートを読み取って、そのアカウントっぽいツイートをしてくれる

https://no-code-ai-model-builder.com/tweet-me

https://www.tweetstorm.ai/


### 歴史上の人物とChatできる
https://chatbotkit.com/apps/peopleai

### エラーコードを修正してくれる
https://useadrenaline.com/

### ファッションについてアドバイスしてくれる
https://apps.chatbotkit.com/fashionai

### ビデオを作成してくれる
https://filmforge.uwu.ai/

https://www.videomakerai.com/


### ブログ生成
https://magicblog.ai/


### マッチングアプリのプロフィール作成
https://www.lovegenius.io/

そのほかにも「これ面白い！」と感じたものがあれば、是非ともコメントください！
エンターキーの重み

(カチャカチャカチャ・・・)
(ッターン！)

# はじめに
みなさんエンターキーは押してますか？

普段は気軽に押せても、インフラ作業中は重みが違ってきます。
以前私がオンプレ環境で運用をしていた頃、
エンターキーを押す(コマンド実行の)直前に心がけていた事を紹介しようと思います。

※Apacheの例が中心ですが、特に悪意はなく例えが思いつきやすかっただけです。

# 1. 何に対して、何を行うのか
今から実行するコマンドには何かしら目的と期待する結果を生む。
手順書に書いてあるとはいえ、対象は何で、どのような作用を期待しているのかを再認識する事。

- 例えば、Apacheの再起動一つにしても、意味もなく実行する事はない。
    - それがコンフィグ変更の適用なのか?
    - メモリ使用量の高いプロセスを落とす為の一時対応なのか?

目的を果たせない作業は失敗、必ず目的を念頭に置いてエンターキーに挑む事。


# 2. 実行時に何が起きて、どうなるのか
今から実行するコマンドで何かしらが動作して、プログラムの動作が変わるはず。
後続で確認手順があるとはいえ、想定外の挙動があればすぐに対処に回れる準備をしておく事。

- 例えば、Apacheの再起動一つにしても、
    - 停止時に通信中ユーザーとのセッションはどうなる？
        - アラートが飛ぶなら事前連絡や一時停止は完了しているか
    - 子プロセスはどの程度の時間で入れ替わる？
    - コンフィグ読み込み順序の影響で他のホストにも影響していないか?

些細な構成ドリフトが問題を引き起こすことはザラにある。
コマンドが帰ってこない、開始時にコンフィグエラーが発生したなど想定外の挙動に落ち着いて対処する事ができる。


# 3. 正常と判断する為に何を確認するのか
コマンドを実行した後、期待した結果をどうすれば確認できるか想定しておく事。
実行後に最も早く正常に完了したかを確認できるのは自分。
確認手順に不足がある可能性まで疑う、手順書作成時と作業時の集中力は別物。

- 例えば、Apacheの再起動一つにしても、
    - プロセスの起動時刻は更新されているか、古いものが残っていないか？
    - ポートは想定通りにリッスンしているか?
    - アクセスログは意図した内容で流れているか？

正常に完了せず次の手順に進んだり、間違っていた場合は大きな手戻りや取り返しのつかない問題に繋がりかねない。

# 4. 異常と判断する為に何を確認するのか
実行したコマンドにより、異常が起きた場合の影響範囲を想定しておく事。
異常発生時に最も早く切り分け作業に当たれるのは自分。
判断がつかず、一人でモタモタ再現を取っている場合ではない。

- 例えば、Apacheの再起動一つにしても、
    - 特定ホストとの通信ができなくなった
    - 新規追加ログのrotateが機能していなかった
    - 一部のrewriteが機能しなくなった

インフラ作業には正常完了報告後に徐々にシステムを蝕むミスも存在し、大きなダメージを受ける事も多い。
異常の早期発見により被害や緊急対応を最小限に抑えることができる。

# 5. 問題が起きた時に切り戻す手順はどうするか
システムを元の挙動に戻せるよう、切り戻し手順を用意しておく、忘れがち。
不可逆な作業もあるが、元に戻す手順やバックアップなど手段は可能な限り用意をしておく事。

- 例えば、Apacheの再起動一つにしても、
    - 元のコンフィグをバックアップしておく
    - 予めetckeeperを導入し切り戻し手順を用意しておく
    - 異常筐体を切り離す

可能な限り迅速に切り戻せる手順を用意しておく事で、安心感は格段に上がり落ち着いて対応ができる。
複数の選択肢があればより良く、対応に余裕ができる事も多い。

# 6. 勇気
最後にエンターを押す、その一手が恐い、重い。
覚悟を決めるとも言え、これらを考え正しく恐れる事。

背中を押してくれた言葉をいくつか記載しておく。
> 勇気とは恐怖を感じないことではない。恐怖を感じながらも行動できることである  - (M・スコット・ペック)

> 最悪のケースを想定しておけば、それより悪くないと安心できる - (同僚A)

> 今より悪くならない、誰も死なない - (同僚B) 障害復旧の為、不可逆なコマンドを打とうとしている時
(命に関わるシステムを扱ってる方には対象外)


# さいごに
これらはインフラがしっかり整ってる環境やシステムの可用性/仕組み/文化次第で不要かもしれません。
昨今はクラウドサービスの台頭で「コマンドなんて打たへんわ！」って時代でもあります。
ですが、重大なリリース直前や、クラウドサービスでも構成変更直前に数秒でもこれらを考える価値は感じています。
エンターを押さず(ボタンクリックせず)に黙り込んでる時は、せかさず優しく見守ってあげてください。

「動いていて当たり前」「作業(結果)は地味、障害は派手」「手汗がすごいですね」など色々言われましたが、
こういうスリルと刺激の中で作業している事が伝われば嬉しく思います。

心地よくエンターキーを押せる一助になれば幸いです。

(ッターン！)
「ん〜・・・ それじゃあいっちょ土下座でもかましてきますか」
【備忘録】NoMethodError: undefined method `change_contents' for #<RubyXL::Cell..... 

rubyXLを3.4.0以降のバージョンに上げたときに

```
NoMethodError: undefined method `change_contents' for #<RubyXL::Cell(1,1)...

```
みたいなエラーが出ました。

3.4.0以降のバージョンからは「メモリの節約のために使うメソッドだけrequireしてね」ということになったみたいです。

> require 'rubyXL/convenience_methods/cell'
require 'rubyXL/convenience_methods/color'
require 'rubyXL/convenience_methods/font'
require 'rubyXL/convenience_methods/workbook'
require 'rubyXL/convenience_methods/worksheet'

https://github-com.translate.goog/weshatheleopard/rubyXL/issues/328?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja&_x_tr_pto=sc#issuecomment-470805721

これを書いておけばとりあえず全てのメソッドが使えるようになるみたいですが、せっかくなので有効活用したい...でも何にどのメソッドが含まれているかわからない...
``` 
require 'rubyXL/convenience_methods
```

書き出してみました、

https://qiita.com/nu_368/items/8446a854a7fd8521566f


が、同名のメソッドとかもあったのでメソッド名と照らし合わせてrequireするファイルを探していくよりは、トライアンドエラーで成功するまでファイルを順に追加していく方が簡単そうです。

自分の場合は```cell```と```worksheet```をrequireしておけばなんとかなりそうでした。
laravelでメール認証ユーザーとTwitter認証ユーザーの分岐

ログインしているかどうかのif文なら調べると出てくるのですが、ログイン方法が通常（メールアドレス）ログインかTwitterログインかで分岐する処理の書き方にはまってしまったので個人的メモ。

# やりたいこと
ユーザーのログイン方法がTwitter認証だったらツイートボタンを出す。
メアド認証だったらそれ以外の共有ボタンを出す。

# 前提
通常のuserテーブルのカラムに加え、Twitter認証をしているユーザーはidを格納するtwitterカラムがある。（詳細は省略）

# 結論

```
@if(Auth::user()->twitter)  //twitterカラムに値が入っていたら
 // Twitter認証ユーザー向けの処理
@else 
 // メール認証ユーザー向けの処理
@endif
```

間違いなどありましたらこっそり教えてください……。
メールアラート設定でメールアドレスを受信者として設定する方法

こんにちは、ジャンです。

メールアラートを設定する際に、ユーザや公開グループなどを指定することは簡単ですが、
特定のメールアドレスを受信者として指定するためにはどうすればいいですかね。

今回は、メールアラート設定でメールアドレスを受信者として設定する方法をご紹介いたします。

<h4>１．メール項目作成</h4>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995724/a4c0f871-e5a1-abdb-052a-d01323df3967.png)


まず、対象のオブジェックでデータタイプが<strong>メール</strong>である項目を作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995724/d79c654d-fa60-7e64-b688-1e014749a5ea.png)

その後、表示ラベル、項目名を入力
また、<strong>デフォルト値に受信者アドレスを入力</strong>します。



<h4>2.メールアラートの設定</h4>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995724/9e9dfc24-2dfd-211d-4732-767e8746739e.png)

オブジェクトとメールアラートを選択
受信者種別で「メールの項目」を選択し、作成したメール項目を追加します。


これで、メールアラートに特定のメールアドレスを設定することで完了です。
【Flutter】TextStyle.heightを調整しよう

## 初めに
[TextStyle](https://api.flutter.dev/flutter/painting/TextStyle-class.html)にはいくつものプロパティが存在し、幅広いカスタムが可能です。
今回は、行間を調整する[height](https://api.flutter.dev/flutter/painting/TextStyle/height.html)プロパティを見ていきましょう。

## 行間とは
行間とは、文字列を表示する際の実際の高さを示しています。
実は、`fontSize: 20`を指定したからといって`Text`Widgetの高さが20pxになるわけではありません。
これは、[LineMetrics](https://api.flutter.dev/flutter/dart-ui/LineMetrics-class.html)クラスが Font の種類に合わせて適度な余白を上下に設定してくれるためです。

以下をご覧ください。※わかりやすいように色付きのContainerで囲っています。
|適度な余白|余白なし|
|:---:|:---:|
|<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552610/dcb8003d-ab5e-e118-0f3c-332452d31d99.png' width=300>|<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552610/69843bab-b3a8-3e0c-7a6f-accb3eacec97.png' width=300>|
|TextWidgetの高さ: 60px|TextWidgetの高さ: 40px|

アプリの仕様にもよるため、どちらがいいとは明言できませんが調整方法を知っておくことが大切ですね。
では実際にその調整方法を見ていきましょう。

## 行間の調整方法

行間は`TextStyle.height`で調整が可能です。ドキュメントを見てみまよう。

https://api.flutter.dev/flutter/painting/TextStyle/height.html

なるほど。行間は、
<font color="Red">**行間　＝　FontSize　* height**</font>
で表現されているようです。行間は直接高さを設定するのではなく、**フォントサイズの何倍か**で指定するんですね。

`fontSize: 20`に指定し、確認すると確かに、行間は`fontSize　* height`になっていました。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2552610/f36bf0c7-5e7d-55be-367c-c924cf6b38cb.png' width='300' />

初めにも述べましたが`height`に`null`または何も指定しないと、`LineMetrics`クラスが Font の種類に合わせて適度な行間を指定してくれるみたいです。
サンプルのようにアルファベットの場合、行間は`24px(height: 1.2)`でしたが、日本語テキストの場合は`30px(height: 1.5)`となりました。

## 最後に
テキストの見栄えはアプリ全体の見栄えに大きく繋がると思うので行間は適切に設定しましょう！
アプリの紹介画像を簡単かつおしゃれにする方法


![iphone-12-pro-mockups-63d33c7fda95e232fa89fb35@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/dbd38cc7-bb4a-02be-3b00-18171ea02b29.png)


こんにちわ。いせきです。早く春が来てほしいですね。でも春が来たら、大学院＋会社勤めがあるから修羅の道になりそうです。でも頑張るしかないですね。頑張ります。



# 本題

今回は、スマホアプリを出す方にとってとても便利になるような情報を共有します。
アプリの紹介画面をとても簡単におしゃれにできます。

こちらのサイトです。

https://artboard.studio/mockup-items

僕が使ってみたのですが、ほんとに便利かつ簡単で、めっちゃいいデザインで完璧でした！お金を払いたいくらいです。でも僕は無料で使えました。
使い方はとてもわかりやすくまとめられているものがあるのでそれを参考にしてください。

https://www.unprinted.design/articles/creating-3d-mockups-using-artboard-studio/


<b>僕が作ってみた画像がこちらです。</b>



![iphone-12-pro-mockups-63d33c7fda95e232fa89fb35@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/aba8a6b2-4c09-2db8-2347-18b4deedd949.png)


どうでしょうか？正直今までにないくらいとても便利だなと感じることができました。


# 宣伝
今回、家計簿のアプリをリリースしました。

収支を記録するアプリを作りました。収支だけでなく値引きできた時の額も記録し、どのくらい節約できたのかも記録できます。広告も実装しているので、少しでも触っていただけると幸いです。
また、星をつけていただけると嬉しいです。


https://apps.apple.com/jp/app/%E7%AF%80%E7%B4%84-%E5%AE%B6%E8%A8%88%E7%B0%BF/id1660345986 


# 最後に
このサイトはほんとに革新的だと思いました。これでいい紹介画像が作れました。
個人開発をしている皆さん、頑張っていきましょう。
[Jest][備忘録] __mocks__フォルダにクラスのmockを作成した時の落とし穴

# TL;DR

- `__mocks__`フォルダに定義するクラスは、必ず実体と同じ名前で定義
    - `export`も同じ名前にする
- テストで使う時に実体と同じ名前だと混乱するので、下記のように`import`時に別名をつけてあげる
    - `import { ExampleClass as MockExampleClass } from '../infrastructures/repositories/__mocks__/ExampleClass'`

# 環境

```txt
MacOS 13.1
Node.js 18.12.1
npm 8.19.2
typescript 4.9.3
jest 28.1.3
ts-jest 28.0.8
```

# つまづいたこと

jestの[マニュアルモック](https://jestjs.io/ja/docs/manual-mocks)ドキュメントにあるように、`__mocks__`フォルダ配下にモックモジュールを定義できる。
テストファイル側で`jest.mock('./moduleName')`としてやれば、そのモジュールの実体が実行されてしまうことはなく、全てjestのmock関数に置き換えられる便利な代物だ。

しかし、クラスのmockモジュールを`__mocks__`フォルダに作成、テストを実行したところ、下記のエラーが出力されてテストがFAILした。

>TypeError: "x" is not a constructor

## その時の実装

実体側

```ExampleClass.ts
class ExampleClass {
  // 省略
}

export { ExampleClass }
```

mock実装

```__mocks__/ExampleClass.ts
class MockExampleClass {
  // 省略
}

export { MockExampleClass }
```

こうしたのは、クラス名として`Mock`をつけておいた方が、テストファイルで利用する時に実体なのかmockクラスなのか分かりやすいだろう、という思いから。
しかしこれが良くなかった。

# テストが落ちる理由

もし実装側で`ExampleClass`をインスタンス化する処理があったとする。

```otherModule.ts
import { ExampleClass } from './ExampleClass'

const exampleClass = new ExampleClass()
```

テスト側で`ExampleClass`をmockした場合、`otherModule.ts`でimportが参照するのは`MockExampleClass`になってしまい、コンストラクタ名が一致しないため`new`できずに落ちていた。

```otherModule.spec.ts
jest.mock('./ExampleClass')
// ->import { ExampleClass } from './ExampleClass' している箇所は
// 全てMockExampleClassを参照するようになってしまう
```

# 解決策

- `__mocks__`フォルダに定義するクラスは、必ず実体と同じ名前で定義する
- exportも実体と同じ名前にする
- テスト側で実体とmockクラスが同じ名前で良いのならそのまま使えば良いが、テストの可読性が悪いため、下記のように別名をつけてimportする方が良いと思われる。

実体側

```ExampleClass.ts
class ExampleClass {
  // 省略
}

export { ExampleClass }
```

mock実装

```__mocks__/ExampleClass.ts
/**
 * ExampleClassをmockしたクラス
 *
 * 実体と同じクラス名で定義・exportしないと、テスト実行時、実装ファイルでインスタンス化できなくなってしまう。
 * テストファイルでimportする時は可読性向上のため、`import { ExampleClass as MockExampleClass }`のように別名をつけること。
 */
class ExampleClass {
  // 省略
}

export { ExampleClass }
```

テストファイル

```otherModule.spec.ts
import { ExampleClass as MockExampleClass } from '__mocks__/ExampleClass'
```

# 参考

https://jestjs.io/ja/docs/manual-mocks
ACSのSQLスクリプト実行画面からCLコマンドを実行したい

レガシーなご質問をいただきまして

Q.ACSなどSQLスクリプト実行画面からIBM i CLコマンドやユーザープログラムを実行したい

A.SQL実行画面で　頭に CL: とつけて続けて実行したいCLコマンドやユーザープログラム名を指定してください。

こんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/039f82a7-6264-eac8-ee81-a26fbdac9e9f.png)

上記はユーザー作成プログラム　BCHJOB01 をバッチジョブ投入しています。
結果はこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/a2800cc4-150f-ec55-96c9-1c342b70cd95.png)

このやり方では、投入したACSなどのSQL実行画面では投入された実行プログラム実行結果が判断できないため、何らかの確認方法を考える必要はあります。（CL:のあとのコマンドが正常実行できなかった場合はエラーが返りますが・・下記例はコマンドストリングが間違っています）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/8a302288-3582-1b6a-3ee5-c2c9062b5e2a.png)
サービスの名前を考えるときにやったこと

## サービスの名前決めるのって難しくない？
なんかつくろうってなったときに、サービス名決めたくなりますよね。
私は、サービスの名前決まると愛着が急にあがったり、わくわくしてモチベもちょっとあがります🥰

でも私は頭かたいからそんな良いアイディアがｽｯ!!と出てこないし、
「なんかちげぇな～～🙄」って思いながら一生迷ってしまいます。。。

それでも何とかいろいろ試行錯誤しながら、サービス名(仮)を考えてみたので、そのときに試してみたことを書いていきます🤗

我流なので、もっといい考え方があるかもですが、一部でもいいので参考になったらうれしいです🥰

### 使ったツール
[miro](https://miro.com/ja/)でワークをしました！
こういうホワイトボードツールは、割と思考が発散して、意見がでやすいので、質より量を出すことが大事なワークにはもってこいだと思います

## 決めた流れ
* [作るテーマ(サービス)を思い返す](#使ったツール)
* [キーワードを一旦思いつくだけいっぱい書く](#キーワードを一旦思いつくだけいっぱい書く)
* [キーワードから連想ゲームをする](#キーワードから連想ゲームをする)
* [サービス名っぽいのを作ってみる](#サービス名っぽいのを作ってみる)
* [いいものを選別する](#いいものを選別する)

### 作るテーマ(サービス)を思い返す
「そんなのもうばっちり頭にあるよ🥱」って感じかもしれないですが、改めて思い返したり、書いてみると次にやるキーワード出しがやりやすい気がします👍
私は、コンセプトやペルソナが存在したので、それを見返してみました

### キーワードを一旦思いつくだけいっぱい書く
なんでもいいから、そのサービスにかかわりそうなキーワードをいっぱい挙げます。
これはめちゃ難しかったんですが、下記をイメージしみるとキーワードをあげやすいかも？？と思ったので、いくつか挙げてみます
モノや動作だけではなく、感情とかもいれてみてもいいかも😶

* ユーザーは誰？
* そのサービスはなにをしてくれる？
* どんな時につかうの？
* ユーザーはどんな行動をする？
* 使うとユーザはどううれしい？
* 使うとユーザはどんな状態、気持ちになる？
* 似てるサービスの名前は？

書く時は本当にしょうもないな～って思ったキーワードでも書いておくとそこから他の人が何か思いついたり、
別の発想が出てきたりするので、どんなことでも頭にとどめずに書くといいきがします🤸‍♀️

書くのはマインドマップとかだとつながりがわかりやすくて書きやすいかもです(↓こういうの)
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462497/5ae9bc42-113a-61de-5df7-4fea73ed0818.png">

### キーワードから連想ゲームをする
どんなやり方でもいいんですが、出たキーワードから連想ゲームをしましょう。マジカルバナナ的な🍌

1. 類義語を探してみる
ある程度自力で考えたら、[連想類語辞典](https://renso-ruigo.com/)を使って考えてみました
例) ごはん → いただく、めし、つまみぐい...

2. 擬音を探してみる
動作をするときにどんな音がなるかな、どんな言葉で表すかなを考えました
例) ごはん → もぐもぐ、ぱくぱく、ホカホカ、...

3. キーワードから思いつく格言、ことわざを書いてみる
これもしてみても面白そうといってくれた方がいたんですが、学のない私には思いつかなかった＼(^o^)／

これを繰り返したりして、いろんなキーワードをいっぱいだしました。

### サービス名っぽいのを作ってみる
いろんな変換や融合をしてサービス名っぽいのをつくってみましょう🎈
わたしはこの辺をやりました！
1. キーワードを英語やローマ字にしてみる
安直ですが、英語やローマ字変換すると急にそれっぽくなったりします
例) つまみぐい → Nibble
例) もぐもぐ → MoguMogu

2. 組み合わせる
キーワードを組み合わせてみました。ローマ字にしたあとに組み合わせたり、、、
例) めし＋ぱくぱく → MESHI PAKU (めしぱく)
 
3. ～～ly とかをつけたり、省略してみたり、別の言い方にかえてみたり
例) Nibble(つまみぐい) → Nibbly
例) もぐもぐ → Mogoo

4. 自動生成サービスに頼ってみる 
だいぶ煮詰まってきたら、キーワードを入れると自動でサービス名を作ってくれる[Namelix](https://namelix.com/)サイトを使ってみました！わたしはそこから新しいキーワードを見つけたりできました

#### 思い詰まったら。。。
他のサービスがどんな由来でどんな名前にしているかは結構参考になるかもしれません…！

私が最近知っていいなと思ったのは、
筋トレする人たちがよく食べてるヨーグルトの「oikos」って
「自分を追い越す」から来ていることを知りました・・・！！(めちゃいい💪)

最近はやっているサービスとかお気に入りのサービスの名前からも名前の発想が得られるかもしれないです...！！


### いいものを選別する
ある程度候補を出し切ったら、この辺の条件を満たすもので絞りました🤝
* 呼びやすいものになっている
* コンセプトが表れている、イメージがあっている
* すでにサービス名が存在してない

その後チームのメンバーの中で1人3票くらいで投票して、多数決で決定しました🎉
めでたしめでたし。

## おしまい

わたしは名前決まってから、無事モチベが(ちょこっと)あがりました😎
みんなも名前決めてモチベあげよう！！！！
Azure Administrator(AZ-104)：Azure での ID とガバナンスの管理「ロールの割り当て」

Microsoft Learnを用いたMicrosoft Azure Administrator(AZ-104)の試験内容をまとめる投稿です。
この投稿ではMicrosoft Learnで学ぶ内容をできるだけ簡潔にまとめております。
Azureの勉強を一から始め、AZ-900取得後の資格としてAZ-104取得を目指している方の参考になれば幸いです。
※AZ-900の内容は本投稿では省略しております。再度復習したい方は下記をご参照ください。
[Azure Fundamentals(AZ-900)：試験合格に向けた学習内容のまとめ](https://qiita.com/fsd-jume/items/e4ec76959adb547ac5e8)

## 今回の学習内容
**◆「ロールの割り当て」**
◇対応するMicrosoft Learn ラーニングパス
[AZ-104:Azure での ID とガバナンスの管理](https://learn.microsoft.com/ja-jp/training/paths/az-104-manage-identities-governance/)
◇対応するモジュール
[ロールの割り当てを作成する](https://learn.microsoft.com/ja-jp/training/modules/configure-role-based-access-control/4-create-role-assignment)

※前回の投稿は下記から確認できます。
[Azure Administrator(AZ-104)：Azure での ID とガバナンスの管理「ロール定義」](https://qiita.com/fsd-jume/items/2f16ce98ad9e94c22e89)

## ロールの割り当て
・特定のスコープでセキュリティプリンシパルにロール定義をアタッチするプロセス
・ロールの割り当てを作成することでアクセス権を付与
・ロールの割り当てを削除することでアクセス権を削除

### ロールを割り当てる手順の例
①アクセス権を付与するセキュリティプリンシパルを決める(グループA)
②付与したいアクセス権を持つロールを選択(ロール4)
③アクセスが必要なスコープを特定(リソースグループa)
④ロールを割り当て(それぞれを紐づける)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851723/b22fd7d8-e267-fc44-af32-b677f30476a5.png)

### グループへのロールの割り当て
・グループにロールを割り当てると、そのグループ内のメンバーにもアクセス許可を付与

**◆グループへのロールの割り当ての例**
・セキュリティプリンシパル：グループA
・割り当てロール：共同作成者
・スコープ：リソースグループa
・グループBはグループAのメンバー
・ユーザ1はグループBのメンバー
⇒ユーザ1もリソースグループaに対して共同作成者のアクセス許可が付与
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851723/03a5b092-c384-5e6b-10f5-a613a0867b90.png)

### 複数のロールの割り当て
・Azure RBACは加算式のモデル
・複数のロール割り当てが重複した場合
⇒ロール割り当ての重ね合わせが実際のアクセス許可

**◆複数のロールの割り当て例**
・割り当て1
　-ユーザA/サブスクリプションa/共同作成者ロール
・割り当て2
　-ユーザA/リソースグループa/閲覧者ロール
⇒ユーザAは実質的にサブスクリプションaの共同作成者ロール
⇒閲覧者ロール割り当ての効果はない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851723/945de163-1725-1d07-d87b-d28a472174f9.png)

### 拒否割り当て
・ロール割り当てと同様にアクセス拒否の割り当てが可能
⇒ロールの割り当てより拒否割り当てが優先される
・特定のスコープでセキュリティプリンシパルに拒否アクションをアタッチ
・許可されないアクションのセットを定義
・Azure Blueprints/Azureマネージドアプリでのみ使用可能

## 次の学習内容
**◆AzureロールとAzure ADロール**

https://qiita.com/fsd-jume/items/9ce7d85d89822cf5e559

## 学習内容をまとめたページの一覧

https://qiita.com/fsd-jume/items/6eda24728c9c03c36bc3
No.6 カードを追加する

## カードを追加
**1．ビルドから「カード」を選択**
**2．テーブルを展開し、カードで表示したい項目を選択する（今回は「売上」を確認する）**
※基本的には数値や通貨のデータ型を使います
**3．表示されたビジュアルを確認する**
![作成1ezgif-1-fe1862784a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2943951/0b806fc9-5dcc-3150-fb37-0528db171a9e.gif)


## カードの編集
**1．ビジュアルの書式設定を選択**
**2．ビジュアルの「吹き出しの値」で表示単位を自動から「なし」にする（短縮数字ではなく正確な数字が表示される）**
**3．フォントサイズや太さ、配置を適宜変更**
![作成2ezgif-1-57b0ed1974.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2943951/85b13ac3-cd7c-f087-7e51-75cdd64ed9cc.gif)

## カードの編集（カウント方法を変更）
**1．フィールドの下向き印を選択**
**2．表示したい値を選択（今回は平均値を選択）**
![作成3ezgif-1-76762420c1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2943951/11cb94d7-4b25-7a43-acd9-6f09342ebfd4.gif)
これで支店の売上合計ではなく、支店の**売上平均**が表示されるようになりました


## カードの利用シーン
・重要な数字を強調したい時に利用する
**・他のビジュアルと組み合わせて利用する事で絶大な効果を発揮します**

ex.)棒グラフだけでは数字感がわからない
Before　→各支店の数字はなんとなくわかるが。。
![スクリーンショット 2023-02-02 15.14.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2943951/c82487d3-8ddd-03ff-f433-4fb5fc999b6c.png)

**After　→各支店の売上と、全体の合計と平均がひと目でわかる**
![スクリーンショット 2023-02-02 15.17.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2943951/d5f8a449-dd00-a7e9-7748-1343342de17e.png)


ex.)アンケートの平均点を確認する
Before →なんとなく高い点数が多そう？8点、7点が半分くらい占めているのはわかるけど。。
![スクリーンショット 2023-02-02 15.24.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2943951/7476ea8f-90b5-2b82-7242-fa821108a80c.png)

**After　→全体の平均点がひと目でわかる。何名参加したのかというのも円グラフ上で計算せずともすぐわかる。**
![スクリーンショット 2023-02-02 15.34.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2943951/82bab73b-1933-14e9-29b1-afcf90b8ba11.png)




こちらのセッションは以上です。
[→ Power BI サービス練習帳に戻る](https://qiita.com/shinyasasaki/items/391d50c2508794e8fcfd)
Storybook7がSvelteKitに対応するみたいなので我慢できずにBeta版を導入してみた

2022/12/22にStorybook7がBetaになったことが発表されました。Storybookはアプリケーションを介さずにコンポーネントを単独で開発できる便利なツールですが、Storybook6をSvelteKitで使用するには色々と設定の手間がかかりました。

今回のStorybook7ではSvelteKitへ正式対応するようなので、どのくらい簡単に導入できるようになったのか試していこうと思います。（Beta版なので正式リリース後は本記事の情報とは異なる場合があります）

## SvelteKitの環境を用意
公式の導入方法に従って新しいプロジェクトを作ります。（※要Node.js v18以降）
```sh
$ npm create svelte@latest my-app
$ cd my-app
$ npm install
$ npm run dev -- --open
```
とりあえずTypeScriptでテストやLintなど盛々構成で作りました。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2221418/9f95cfc4-15b9-b26c-d991-33dfa88b3ec6.png)
インストールが完了するとブラウザにWelcomeページが表示されます。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2221418/cee26248-f440-3772-0adf-b28597929e38.png)
## Storybook7(Beta)のインストール
[Storybook 7 migration guide](https://chromatic-ui.notion.site/Storybook-7-migration-guide-dbf41fa347304eb2a5e9c69b34503937)に従ってStorybook7(Beta)をインストールします。
```sh
$ npx sb@next init
```
インストール中に *Do you want to run the 'eslintPlugin' migration on your project?* と聞かれるので、デフォルトの *Yes* を選択しました。

インストールが完了したら起動してみます。

```sh
$ npm run storybook
```

Storybook6のときは初期状態ではエラーが出て起動ができなかったのですが、7(Beta)では問題なく起動できました！
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2221418/47eb162f-6914-1787-9e1b-9e4baf3f8f05.png)
Exampleのコンポーネントもちゃんと動いています。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2221418/8b22203b-989a-9dce-4467-c87a889b4065.png)
## コンポーネントを追加してみる

### Svelteコンポーネント
背景色をpropsで設定できるボタンを作ります。

*/src/components/Sample.svelte*
```html
<script lang="ts">
	import './sample.css';
	
	export let bgColor: string;
	export let label: string = '';
</script>

<button class="button" style="background-color: {bgColor};">
	{label}
</button>
```
*/src/components/sample.css*
```css
.button {
    font-size: 1.5rem;
    font-weight: bolder;
    color: white;
    border-radius: 0.5rem;
    border: 0;
}
```
### Storybookコンポーネント定義
*/src/stories/Sample.stories.ts*
```ts
import type { Meta, StoryObj } from '@storybook/svelte';

import Sample from '../components/Sample.svelte';

const meta = {
	title: 'My Components/Sample',
	component: Sample,
	parameters: {
		layout: 'fullscreen'
	},
	tags: ['autodocs'],
	argTypes: {
		bgColor: { control: 'color' }
	}
} satisfies Meta<Sample>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {};
```
### Storybookで動作確認
作成したコンポーネントがカタログに表示されました！
Storybookなので当然のことですが、背景色の指定やラベルの編集ができるようになりました。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2221418/5a5c134c-316e-36d4-5347-0142e55319c1.png)
## まとめ
SvelteKitへのStorybook7(Beta)導入は全く手間がかからず、非常に簡単なことがわかりました。これは正式リリースが待ち遠しいですね。
### 注意
Storybook公式曰く、破壊的改変のフェーズは終わり安定化に向けて作業中とのことですが、とはいえBetaなので正式なプロジェクトで使用するのは避けたほうが良いと思います。
## 参考
SvelteKit
https://kit.svelte.dev/

Storybook
https://storybook.js.org/

Storybook7 Beta (Blog)
https://storybook.js.org/blog/7-0-beta/
Mock Service Workerを使ってサーバレスでE2Eテストを実施する

## 概要
- [前回](https://qiita.com/tenda_ryo_y/items/4ee8e7b05b026fc985e5)は[Mock Service Worker](https://github.com/mswjs/msw)(以下MSW)のデモを使って仕組みを見ていきました
- 今回も同デモを使用してE2Eテストの流れを見ていきます
  
## 準備
[前回の記事](https://qiita.com/tenda_ryo_y/items/4ee8e7b05b026fc985e5)を参考にMSWのデモ用ブランチからローカルに実行環境を用意してください。

## E2Eテストコードを見てみる
E2Eテストコードは **examples/rest-react/e2e** に格納されています。

MSWはテストスクリプトに仕込むmockと異なり、ブラウザのリクエストをインターセプトする仕組みなのでテストコードに専用の実装を施す必要はありません。またJavascriptのアセットである[Service Worker API](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API)を利用しているので別途モックサーバを準備する必要もありません。

このデモに付属している以下のE2EテストコードはCypressを使用した初歩的なコードになっています。

*examples/rest-react/e2e/Login.e2e.test.js*
```js
describe('Login', () => {
  before(() => {
    cy.visit('/')
  })

  describe('given I logged in using existing user', () => {
    before(() => {
      cy.get('#username').type('johnUser{enter}')
    })

    it('should display my user ID', () => {
      cy.get('[data-testid="userId"').should(
        'have.text',
        'f79e82e8-c34a-4dc7-a49e-9fadc0979fda'
      )
    })

    it('should display my first name', () => {
      cy.get('[data-testid="firstName"]').should('have.text', 'John')
    })

    it('should display my username', () => {
      cy.get('[data-testid="lastName"]').should('have.text', 'Maverick')
    })
  })
})
```

例のごとくこのコードにはバグが含まれているので、以下のように修正します。修正のついでに入力された username の検査も追加していきます。

```js
describe('Login', () => {
  before(() => {
    cy.visit('/')
  })

  describe('given I logged in using existing user', () => {
    before(() => {
      /** 入力値を hoge へ変更 */
      cy.get('#username').type('hoge{enter}')
    })

    it('should display my user ID', () => {
      cy.get('[data-testid="userId"').should(
        'have.text',
        'f79e82e8-c34a-4dc7-a49e-9fadc0979fda',
      )
    })

    it('should display my first name', () => {
      cy.get('[data-testid="firstName"]').should('have.text', 'John')
    })

    /** この検査概要に記載ミスあったので修正 */
    it('should display last name', () => {
      cy.get('[data-testid="lastName"]').should('have.text', 'Maverick')
    })

    /** username の検査 */
    it('should display my username', () => {
      cy.get('[data-testid="username"]').should('have.text', 'hoge')
    })
  })
})

```

コマンドラインからE2Eテストを開始します。
```sh
$ yarn test:e2e
```

MSWとのfetchが正常に行われ、E2Eテストの結果は成功しました。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2221418/27511386-5bd7-cba1-3007-e92eeffae4a8.png)
次は username の検査文字列を少し変えてテストしてみます。正しくテストできているのであれば、この検査は失敗するはずです。

```js
cy.get('[data-testid="username"]').should('have.text', 'hogeAA')
```

期待通り、テストに失敗しました。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2221418/ec7cffd2-32b4-2baf-a76e-60aac039b776.png)
## 最後に

このようにMSWを利用することでE2Eテストで使用するサーバサイドAPIモックをサーバレスで簡単に構築することができますので、CI/CDでの活用も期待できますね。

## 参考

https://github.com/mswjs/msw

https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
Attention Is All You Need: トランスフォーマー

# 論文
https://arxiv.org/abs/1706.03762
Submitted on 12 Jun 2017
cited by 64332
Jakob Uszkoreitさんは、RNNの代わりとしてself-attention考案していた。これまでAttentionはRNNに適用されていた

# 結論
* Attention機構があればRNNいらない
    * レイヤーごとの計算量が小さい
    * 並列計算できる
    * 遠距離も直接参照できる
    * Attentionの強さ表示で、推論を理解・解釈可能

# 感想
* Attentionの大切さを世に知らしめた
* BertやGPTなど、NLPモデル発達の基礎となった
    * BertはTransformerのEncoderのみ、GPTはDecoderのみを利用
* 実際に、NLPでRNNはほぼ駆逐された
    * NLP以外ではTimeSriesが対象範囲だが、ここはDL以外がSOTA

# 詳細
![Screen Shot 2023-02-02 at 16.08.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3123768/7d6cbe92-4b18-69b2-5893-e2bf5600d17c.png)


### Scaled Dot-Product Attention
![Screen Shot 2023-02-02 at 15.56.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3123768/626f97ab-206b-e0fa-6dab-26fad9802bcc.png)
* scaled = 1/(√dk) 内積を集めたSoftmaxが大きくなりすぎないように
* 系列データや集合データに対してのSoftmax
* Decoderでは、右側の文字をmaskして読まないようにする

### Multi-Head Attention
![Screen Shot 2023-02-02 at 16.05.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3123768/8c3099ec-1eda-e882-cb98-77cb745d0fa0.png)
* Attentionを並行して複数行い、Concat&Affineする
* Q, K, Vの次元は「データ次元/ヘッド数」に下げることで、計算コストを抑える

### その他
* Feed-Foward Networkでは、内部レイヤーの次元を上げて、CNNのChannelのように広げる
* 位置符号をSine・Cosineなどで入れる。位置情報。順序情報。
nuxtにて子から親、そして親から子へデータを渡す

# やりたいこと
子はcomponent。
子Aの値が変更されると、子Bの値も変わるといった処理

子A
```js:nuxt:childA.vue
~~
methods:{
  FormData (data) {
    this.formData[data.key] = data.value
    // childAタブの「パッケージ」が「黄色」(001)の場合
    // childBタブの「バージョン」を「1:ピカチュウ」にする
    // それ以外の場合は「0:通常」にする
    this.pokemonArray.forEach((item) => {
      if ((item.id === data.value)) {
        if (item.package === '001') {
          this.$emit('isVersion', true)
        } else {
          this.$emit('isVersion', false)
        }
      }
    })
  }
}
```

親
```vue:nuxt:parent.vue
<template>
  <div>
    <ChildA
      :version-type="versionType"
    />
    <ChildB
      @isVersion="updateversionType"
    />
  </div>
</template>

export default {
  data () {
    versionType: null
  },
  methods: {
    updateversionType (value) {
    this.versionType = value
  }
}
```

子B
```js:nuxt:childB.vue
~~
props: {
  versionType: {
    type: Boolean,
    default: false
  }
},
watch:{
versionType (newValue) {
  if (newValue) {
    this.version = '1:ピカチュウ'
  } else {
    this.version = '0:通常'
  }
}
```

あとで編集するかもです。
要望があれば。
とりあえずざっくり。
【Tableau】Tabpy Serverのタイムアウト時間（実行処理時間制限）を変更する

# はじめに
TableauでTabpyを使用していると、環境や処理内容によってはタイムアウト（デフォルトの制限時間である**30秒**が経過）して結果が返ってこないということがあるかと思います。
（例えば、API経由で外部の複数オブジェクトやテーブルにアクセスし、データを取得、加工処理をするような場合）
Tabpyはローカルで起動しているTabpy Serverを使用していますので、ここの設定値を変更することで30秒以上掛かるような処理でも結果を返すことができるようになります。

# 制限時間の変更方法
Anaconda3環境にtabpyをインストールした例でご紹介します。
※インストール方法は多くの方が書いてくださっているので、ここでは割愛します。

(ユーザー範囲で)Anacondaをインストールした場合は下記フォルダ内のdefault.confを任意のエディタで開いてください。
例：`C:\Users\(ユーザー名)\Anaconda3\Lib\site-packages\tabpy\tabpy_server\common\default.conf`

そのファイル内の「**TABPY_EVALUATE_TIMEOUT**」の値を変更して、コメントアウトを解除してください。

例）30秒→300秒
```diff_conf:default.conf
- # TABPY_EVALUATE_TIMEOUT = 30
+ TABPY_EVALUATE_TIMEOUT = 300
```

変更後はTabpyの再起動が必要です。

# おわりに
そもそもデフォルトのタイムアウト時間（30秒）を超えないような設計にするのが一番だと思います。
ただどうしてもAPI接続するのにネットワーク環境が悪かったり、大量データに対して時間の掛かる処理をそれほどスペックが高くないPCでしないといけなかったりする場合があるかもしれません。
そのような場合には、今回の設定値を見直してみてはいかがでしょうか。
OpsRamp ワークフローのParallel Multi Instanceについて

本記事では、OpsRamp ワークフローのParallel Multi Instanceについて説明します。
![subprocess-box.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/57482220-3a57-dde2-542f-5acfefdbd5dd.png)

# 概要
OpsRampのワークフローには、Parallel Multi Instanceと呼ばれるループ回数または配列に従い特定のステップを繰り返し実行する方法があります。これを使用することにより、入力された配列をもとに特定のステップを連続して実行することが可能となります。例えば、複数のインシデントIDを入力し、それぞれのインシデントチケットを同ワークフロー内でアップデートするようなことが可能です。
Parallel Multi Instanceは、「Task」または「expanded SubProcess」に設定することができます。
[OpsRamp Parallel Multi Instance](https://docs.opsramp.com/solutions/remediation-automation/process-definitions/processdef-reference/#sub-process-expanded)

# 設定の説明
Parallel Multi Instanceを配置するには、「Task」または「expanded SubProcess」のスパナマークから縦線3本マークをクリックします。
![subprocess_paralell-multi-instance.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/4bd22a06-eb0a-9665-dd92-1df6a8ff84bd.png)

プロパティには、下記のような意味があります。
- Collection: 配列を指定し、繰り返し実行
Collection(テキストボックス): 配列を指定
Element Varialble: SubProcess内で使用される変数 (配列の値が順次この変数に展開されます。)
![subprocess_paralell-multi-instance_property-collection.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/dca6e316-1d30-ab59-e50e-533223a8b76c.png)
- Loop Cardinality: 指定した回数、繰り返し実行
Number of loops: 繰り返し回数
![subprocess_paralell-multi-instance_property-loop.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/509174e7-c1b3-d9e4-de80-6bb1e671c2f7.png)

# 設定例
下記では、インシデントチケットを複数取得し、それぞれのチケットをクローズするような動作をします。
![workflow.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/d9a804fe-f0a4-f3cf-ca39-a6ad6be7f229.png)
- sub_proc(expanded SubProcess)の設定
「Collection」には、前プロセスで取得したチケット情報(配列)を指定します。
「Element Variable」には、SubProcess内で使用する変数名を指定します。
![sub_proc-properties.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/792724dd-020e-96e4-800e-3673e2644c05.png)
- update_incident(Service Task)の設定
「Incident Unique Id」には、sub_procで指定した変数「incident」を使用し、その変数内にある「id」を指定します。
※ 配列の数分、このステップが繰り返され、「id」の値がそれぞれ異なります。
![update_incident-properties.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/f5c71a96-a5f2-bbab-62e4-5cf0c4411f94.png)

# Appendix
- Service TaskにParallel Multi Instanceを設定した場合
![service-task_paralell-multi-instance.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/2ed0a0ea-1bb8-b531-a6e4-1b591251a5ec.png)


---------------------------------------
[<img width = 250 height = 200 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/111de30a-4d33-aa33-5c7d-83d9015093e6.png">](https://www.vistanet.jp/knowledge-base/)
【Unity】既知の問題・修正された問題の一覧

久しぶりに使いに行ったら ☆ が付いてました笑

GitHub にある [Unity バージョン 3 から 2023 までの全リリースノート](https://github.com/sator-imaging/Unity-ReleaseNotes/releases)から、既知の問題・修正された問題を検索して調べられます。バージョン指定も可能。（UTC時間０時に自動更新されます。）

Google、Bing、その他検索エンジンでうまくやってる人もいるかもしれません。

そんな人も `Watch -> Releases` をオンにしておくと新しいリリースの度にメールで通知が届くようになります。

※ `Known Issues` ぐらいは見るようにしようと思ってはいた、けど身に付きませんね。

ちなみに公式のイシュートラッカーってのもあります → [Unity Issue Tracker](https://issuetracker.unity3d.com/)  
ココから厳選された大きな問題が 👆 のリリースノートに載るって感じでしょう。



# 使い方

GitHub の検索エンジンは結構ピーキーなのでコツが要ります。あと、更新ボタンを押さないと何故か結果が表示されない時があります。謎。

--


`<PackageName> Fixed` で修正された問題を、`filename:known <PackageName>` で既知の問題を探せます。`path:Unity<Version>` でバージョン指定も可能です。


- 最近修正された URP 関連の問題（αリリースは除く）
    - https://github.com/sator-imaging/Unity-ReleaseNotes/search?o=desc&q=%22URP+Fixed%22+-alpha&s=indexed

- URP の既知の問題を検索する（Unity 2021）
    - https://github.com/sator-imaging/Unity-ReleaseNotes/search?o=desc&q=URP+filename%3Aknown+path%3AUnity2021&s=indexed

- URP 関連の問題を昇順で一覧する
    - https://github.com/sator-imaging/Unity-ReleaseNotes/search?o=asc&q=URP+issue+path%3AUnity2021&s=indexed


--

Azure も GitHub もインフラただ乗り美味しいです。

以上です。お疲れ様でした。
【Laravel 9.x】Bladeコンポーネント×Eloquentコレクションは速度に注意？

こんにちは、現在エンジニアを目指して勉強中の一般男性です。

ポーフォリオ作品を制作しているなかで
Bladeコンポーネントを使おうとした瞬間にページが重くなったので
メモとして残しておきます。

## 環境
・macOS Monterey 12.6
・PHP 8.1.13
・Laravel 9.3.12
・Docker 20.10.2
・Laravel Sail

## 前提
LaravelのBladeテンプレートで、
同じデザインの要素を何度も繰り返し表示させていたので、
コンポーネント化してスッキリさせようとした時の話です。

結論、Bladeコンポーネントに渡す変数の中身が
Eloquentコレクションだったことでかなり重くなりました。

ちなみにデータの量ですが、
約１０カラムのテーブルから１０件も取ってこない程度。
何万とかそういう話ではありません。。

## 事件を時系列で追っていきます
### 発生当時の状況

繰り返し使っていた要素があったので、
セコセコとコンポーネント化していました。

コンポーネント化が済んだところで画面を確認してみると、、
![スクリーンショット 2023-01-25 16.55.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2535390/66a359fc-4b69-26b3-5a6e-39e0245cd382.png)

なんでやねーん
何回ロードしてもタイムアウトです

### 現場を確認

今回のコードは以下のような感じです。
3つの箇所をコンポーネント化していました。
※表示の関係で`Hoge.html`としていますが、本来はブレードテンプレートです
※簡素化しています

```Hoge.html
<section>
  @component('components.wishLists',
    ['wishes' => $wishes])
  @endcomponent
</section>
<section>
  @component('components.slider',
    ['notes' => $notes])
  @endcomponent
</section>
<section>
  @component('components.notes',
    ['notes' => $notes])
  @endcomponent
</section>
```

### 犯人を捜索 
どこが悪かったのか探っていきましょう。

#### 1, とりあえず全部もどしてみる 
これまでのスピードに直りました。
やっぱりコンポーネント化が原因ぽい。

#### 2, 別の方法でコンポーネント化する

`@component`がダメなのかなと思い、`@include`に変更してみました。
変わらず重いまま、、

```Hoge.html
<section>
  @include('wishLists', ['wishes' => $wishes])
</section>

<section>
  @include('slider', ['notes' => $notes])
</section>

<section>
  @include('notes', ['notes' => $notes])
</section>
```

#### 3, ひとつずつ消してみる

コンポーネント化したこと自体ではなく、3つのうちどれかに原因があるのでは、、
ということでひとつひとつ消してみました。

__するとここでヒット、、！！__
どうも、`$wishes`が重いらしい。。

#### 4, 変数の中身を確認
ということで、`$wishes`と`$notes`の中身を確認。

```Controllers/HogeController.php
$wishes = Wish::with('user')->where('pref_id', $pref_id)->get();
```
```Controllers/HogeController.php
$notes = DB::table('notes')
            ->leftJoin('users', 'notes.user_id', '=', 'users.id')
            ->where('notes.pref_id', $pref_id)
            ->where('notes.deleted_at', null);
            ->select('notes.*', 'users.name', 'users.avatar')
            ->orderBy('note_id', 'DESC')
            ->limit(8)
            ->get();
```


__Eloquentとクエリビルダの違いか、、！？！？！？！？__

### 解決
`$wishes`の取得方法をEloquentからクエリビルダへ
ビクビクしながら変更。

```Controllers/HogeController.php
// これを、、
// $wishes = Wish::with('user')->where('pref_id', $pref_id)->get();

// こうだっ！！
$wishes = DB::table('wishes')
          ->leftJoin('users', 'wishes.user_id', '=', 'users.id')
          ->where('wishes.pref_id', $pref_id)
          ->where('wishes.deleted_at', null);
          ->select('wishes.*', 'users.name', 'users.avatar')
          ->get();
```

__動いたっっっっっ！！！！！！__


## 参考

「laravel Eloquent 遅い」などで検索すると、結構記事が出てきます。
「もう遅くない」という話もありましたが、下の記事は2022/5月のもの。

https://zenn.dev/nicopin/articles/f6d9486af30672

Eloquentでデータを取得すると、付随するメソッドとかも格納するので重くなる
という解釈ができそうです。

https://qiita.com/rin_f_z/items/63e795530af53d460b26



EloquentコレクションをBladeコンポーネントでやり取りしたら
重くなったという話はパッと出てこなかったので、
誰かの参考になれば幸いです。