OmniAICreator/Qiita-1.07M huggingface dataset:
[MySQL] ユーザーの認証プラグインをmysql_native_passwordに変更できない場合の対処法

## 概要
ユーザーの認証プラグインをデフォルトのcaching_sha2_password からmysql_native_passwordに変更しようとしたらエラーになったのでその対処方法の備忘録。

## 環境
MySQLバージョン: 8.0.30 MySQL Community Server - GPL
OS: Windows11

## 手順
対象のユーザー
```
mysql> select user, host, plugin from user where user = 'admin';
+------------------+-----------+-----------------------+
| user             | host      | plugin                |
+------------------+-----------+-----------------------+
| admin            | %         | caching_sha2_password |
+------------------+-----------+-----------------------+
1 row in set (0.00 sec)
```
このユーザーのpluginをmysql_native_passwordにしたい。
```
mysql> alter user 'admin'@'%' identified with mysql_native_password by 'Passw0rd';
ERROR 4058 (HY000): 1 factor authentication method does not match against authentication policy. Please refer @@authentication_policy system variable.
```
1要素の方式だとauthentication_policyに反しているみたいなことを言われる。

現在のauthentication_policyの値を確認。
```
mysql> show global variables like 'authentication_policy';
+-----------------------+-------------------------+
| Variable_name         | Value                   |
+-----------------------+-------------------------+
| authentication_policy | caching_sha2_password,, |
+-----------------------+-------------------------+
1 row in set, 1 warning (0.00 sec)
```
この辺に値の設定の仕方が載っている。8.0.27から追加されたらしい。
https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_authentication_policy

寛容そうな設定に変更してみる。
```
mysql> set global authentication_policy = '*,,';
Query OK, 0 rows affected (0.00 sec)

mysql> show global variables like 'authentication_policy';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| authentication_policy | *,,   |
+-----------------------+-------+
1 row in set, 1 warning (0.00 sec)
```
変更できた。

再度ユーザー変更に挑戦。
```
mysql> alter user 'admin'@'%' identified with mysql_native_password by 'Passw0rd';
Query OK, 0 rows affected (0.00 sec)

mysql> select user, host, plugin from user where user = 'admin';
+-------+------+-----------------------+
| user  | host | plugin                |
+-------+------+-----------------------+
| admin | %    | mysql_native_password |
+-------+------+-----------------------+
1 row in set (0.00 sec)
```
できた。
【Android】斜めの線をCanvasで引く方法

今回は斜めの線をCanvasで引く方法を記載しようと思います。

このやり方は簡単で、縦横の比率が変わっても角から角へ線を引くことができます。


```LineView.kt
class LineView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
) : View(context, attrs, defStyleAttr) {
    var paint: Paint = Paint()
    override fun onDraw(canvas: Canvas) {
        // 線の太さ
        paint.strokeWidth = 4f
        // 線の色
        paint.color = ContextCompat.getColor(context, R.color.black)
        // 線を表示する位置
        canvas.drawLine(0f, height.toFloat(), width.toFloat(), 0f, paint)
    }
}

```

# スクリーンショット
![Screenshot_20221008_230732.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/2aa03548-3046-a160-507d-cf2798617555.png)

このような感じで綺麗な斜め線が弾けてます。

※わかりやすいように枠をつけてます。
今回は左下から右上に向けて引いてます。

```
canvas.drawLine(0f, height.toFloat(), width.toFloat(), 0f, paint)
```

このように引数を変更すると左上から右下に引くことができます。
```
canvas.drawLine(0f, 0f, width.toFloat(), 0f, height.toFloat())
```

以上です。
FastAPIでaiohttp

特に意味はないけどHTTPリクエストを平行に処理し、HTTPステータスコードを足すAPI

```python
from fastapi import FastAPI
import asyncio
import aiohttp

app = FastAPI()


async def get():
    async with aiohttp.ClientSession() as session:
        async with session.get('http://python.org') as response:
            return response.status

@app.get("/")
async def main():
    a, b = await asyncio.gather(get(), get())
    return a + b
```

適切にprintすれば、きちんと非同期処理できていることがわかる。
[Unity]インタースティシャル広告(広告プレースメント)２回目以降の広告も表示されるようにする

# 概要
インタースティシャル広告の一度目はちゃんと表示されたけど、二度目以降のインタースティシャル広告が表示されない。なぜなんだ〜！？となっている方の為の記事です。
(Scene遷移を伴わない場合に必要になると思います)

:::note info
基本的な設定手順は公式サイトにわかりやすく書かれていますのでそちらを参考にしてください
https://developers.google.com/admob/unity/ad-placements?hl=ja
:::

# 本文
```cs

using UnityEngine;
using GoogleMobileAds.Api;
using GoogleMobileAds.Placement;

public class InterstitialScene : MonoBehaviour
{
    InterstitialAdGameObject interstitialAd;

    void Start()
    {
        // インタースティシャルを準備
        interstitialAd = MobileAds.Instance
            .GetAd<InterstitialAdGameObject>("Interstitial Ad");

        MobileAds.Initialize((initStatus) => {
            Debug.Log("Initialized MobileAds");
        });
        interstitialAd.LoadAd();
    }

    // 広告を表示する
    public void OnClickShowInterstitialButton()
    {
        // Display an interstitial ad
        interstitialAd.ShowIfLoaded();
    }

    // インタースティシャル広告が閉じられたら次の広告を準備しておく
    public void OnAdClosed()
    {
        interstitialAd.LoadAd();
    }
}
```


インタースティシャルが閉じられた時(OnAdClosed)の処理でインタースティシャル広告を新しく作り直しておく(interstitialAd.LoadAd)と２回目以降の広告も表示されるようになります。

![スクリーンショット 2022-10-08 22.24.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/e66b89b0-231b-c06e-c2a0-c2f0cbfd39e5.png)
FizzBuzz - HackerRank

最近何度かHackerRankでコーディングテストを受ける機会があったので、HackerRankのテストのコーディング方法について記しておく。

今回は、以下の「FizzBuzz」についてコード例を記載する。

https://www.hackerrank.com/challenges/fizzbuzz/problem
```python:FizzBuzz
def fizzBuzz(n):
    for i in range(1,n+1):
        if i % 3 == 0 and i % 5 == 0:
            print('FizzBuzz')
        elif i % 3 == 0:
            print('Fizz')
        elif i % 5 == 0:
            print('Buzz')
        else:
            print(i)

n = int(input())
fizzBuzz(n)
```
Db2 on CloudをIBM Cloud Activity Tracker with LogDNAのLiteプラン（無料）で監査する

# 記事の概要
本記事ではDb2 on CloudをIBM Cloud Activity Tracker with LogDNAを使用して監査します。

# IBM Cloud Activity Tracker with LogDNAの概要
IBM Cloud Activity Tracker with LogDNA（以下Activity Tracker）は、IBM Cloudのアクティビティーのレコードを取り込み、異常なアクティビティや重要なアクションをモニターすることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/9e33f343-c023-cb3d-41ad-7df73e482e16.png)
ライト・プランでは、ログの行はフォーマット設定されず、またイベントは検索用に保持されないので、ご注意ください。詳しい制約は、[こちら](https://cloud.ibm.com/docs/activity-tracker?topic=activity-tracker-service_plan)から

# 本編
### 記事の前提
Db2 on CloudのLiteプラン（無料）を使用します。作成方法は[こちら](https://qiita.com/nishikyon/items/0219a81673f0b84980da)からご参照ください。本記事と同様に実施するためには、リージョンで「ロンドン」を選択してください。

### Activity Trackerの前準備
**Activity Trackerインスタンスを作成**
1. IBM Cloudに[ログイン](https://cloud.ibm.com/)後、カタログから、または以下のように検索で「IBM Cloud Activity Tracker」と入力し、「カタログの結果」の「IBM Cloud Activity Tracker」からActivity Trackerのページにアクセスします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/da9b18aa-b349-ea2a-74ff-8556ddea4dbc.png)

2. 「ロケーションの選択」では、モニタリングするリージョンを、「料金プランの選択」では、必要なプランを選択します。その後「作成」を実行します。モニタリングする対象と同じリージョンを選択する必要があります。
今回は、Db2 on Cloudをロンドンで作成したので、Activity Traackerもロンドンを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/7f7b6a0b-cb39-c873-1768-a47d8a5fd3d1.png)

3.作成が終わると、リソースリストの「ロギングおよびモニタリング」に表示されたことを確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/d58301f6-ec56-a5a6-6c33-6b44a3e35f98.png)

これにて、ロンドンリージョンのあるDb2 on Cloudを監査することができます。
qtreeパッケージで論理学

qtreeパッケージを使って木構造を書こう．

本文中では数理論理学の例をひいていますが，広く木構造が必要な人に向けて `qtree` はおすすめです．

## さっそく具体例

論理式 $p \land (p \rightarrow q) \rightarrow q$ の構文木を，次のように書くことができる．

入力
```tex 
\Tree 
[.$\rightarrow$ 
  [.$\land$ 
    $p$ 
    [.$\rightarrow$ $p$ $q$ 
    ]
  ] 
  $q$ 
] 
```
出力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539033/22cc3d61-6db1-7140-4e2c-8779b4537348.png)



さらに，論理式 $p \land (p \rightarrow q) \rightarrow q$ のタブロー法による証明は以下のように書ける．

入力
```tex
\Tree 
[.$\neg(p\land(p\rightarrow q)\rightarrow q)$ 
  [.$p\land(p\rightarrow q)$\\$\neg q$ 
    [.$p$\\$p\rightarrow q$ 
      [.$\neg p$ $\bot$ 
      ]
      [.$q$ $\bot$ 
      ]
    ]
  ] 
] 
```
出力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539033/60b100a9-0331-21bd-8fe2-b8004bc416e6.png)


## 公式サイトの紹介

qtree パッケージはこちらのサイトから導入できる．

https://www.ling.upenn.edu/advice/latex/qtree/

`qtree.sty` がパッケージ．
公式のマニュアルは `qtreenotes.pdf` ．


## 基本の使い方
プリアンブルに以下を入力しておく．

```tex
\usepackage{qtree}
```

これで `qtree.sty` が使える．

このパッケージを用いると， `\Tree` コマンドで木構造を書くことができる．とくに `\includegraphics` コマンドとか `figure` 環境とかを用いずとも使える．

親子のみの木は `\Tree [.A B C D ]` のように書く．ドットのすぐ後ろの記号が親になる．
このとき，以下の2点に注意．

- **`\Tree` コマンドと角カッコの間に半角スペースを空ける．**
- **最後の文字と閉じ角カッコの間には半角スペースを空ける．**

これができていないと容赦なくエラーを吐かれる．

入力
```tex
\Tree [.A B C D ] 
```
出力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539033/ff6e1945-81e6-da8c-155f-501d70b4f221.png)


2語以上の言葉を node におくには注意が必要．**半角スペースが構造に反映されるので，それを嫌う場合は`{}`で囲う必要がある．**

入力
```tex
\Tree [.ramen noodle soup {various ingredients} ] 
```
出力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539033/bf1686a8-bbea-a300-46cf-3c9cca15d96c.png)



**要素を折り返す場合は`\\`を挿入する．** 前後に半角スペースは入れない．

入力
```tex
\Tree [.ramen noodle soup various\\ingredients ] 
```
出力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539033/aceb9c55-3168-01df-117c-9bc242bbc8ca.png)


高さが3以上の木は，次のように入れ子構造で書く．

入力
```tex
\Tree [.A [.B E F ] [.C G H ] ] 
```
出力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539033/06691e2b-0305-60ce-8c6e-a3e8e90069f6.png)


木の高さに応じて，**インデントを付けておく**とわかりやすい．半角スペースを忘れずに．

入力
```tex
\Tree 
[.A 
  [.B E F 
  ] 
  [.C G H 
  ] 
] 
```
出力は前図と同様．

## 数式の挿入

`qtree` パッケージでつくる木には，数式を挿入することもできる．

ただし，**「見やすいように」と半角スペースを入れるとそれが木構造の区切りと判定され，目的の木が出力できない．** 最悪エラーを吐かれる．
それを防ぐために，スペースは最低限のみ入れる．

具体的には，

- $A_1 A_2$ を出力したい場合：`$A_1A_2$`と入力する．`$A_1 A_2$`はエラー．
- $A \land B$ を出力したい場合：`$A\land B$`と入力する．**コマンドの直後にコマンドでない文字が来る場合は，半角スペースを入れてよい．**
- $A \lor \neg A$ を出力したい場合：`$A\lor\neg A$`と入力する．**コマンドが連続する場合は半角スペースを入れてはいけない．**

入力
```tex
\Tree 
[.$(p_1\land q_1)\lor(p_2\land q_2)$ 
  [.$p_1\land q_1$ $p_1$\\$q_1$ 
  ] 
  [.$p_2\land q_2$ $p_2$\\$q_2$ 
  ] 
] 
```
出力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539033/ba47e5e9-795d-484d-f050-e177ce3e5410.png)



ほかにもさまざまな機能があるが，さしあたってこれらが使えれば問題ない（と思う）．

この記事が $\LaTeX$ ユーザーの一助になればと思います．
⨯ Apple failed to notarize your application, check the logs for more info Status Code: 2 Message: Package Invalid

electronのアプリの公証でハマったのでメモ。

Package Invalidが出たら原因は書き出された.appの中身に誤りがある。


## .appのバリデーションはxcrun altool を使う
```
xcrun altool --validate-app -f ./your_app_path.app -t osx -u appleId -p appleIdPassword

2022-10-08 22:23:41.500 *** Error: Validation failed for 'your_app_path.app'.
2022-10-08 22:23:41.501 *** Error: The Info.plist in the package must contain the CFBundleShortVersionString key. Unable to validate your application. (-27002)
 {
    NSLocalizedDescription = "The Info.plist in the package must contain the CFBundleShortVersionString key.";
    NSLocalizedFailureReason = "Unable to validate your application.";
}
```

altool doc: https://help.apple.com/app-store-connect/#/devb1c185036



## エラー内容
```
  ⨯ Apple failed to notarize your application, check the logs for more info
Status Code: 2
Message: Package Invalid
Logs: https://osxapps-ssl.itunes.apple.com/itunes-assets/~~  failedTask=build stackTrace=Error: Apple failed to notarize your application, check the logs for more info

Status Code: 2
Message: Package Invalid
Logs: https://osxapps-ssl.itunes.apple.com/itunes-assets/~~
    at /Users/apppath/node_modules/electron-notarize/src/legacy.ts:116:11
    at Generator.next (<anonymous>)
    at fulfilled (/Users/apppath/node_modules/electron-notarize/lib/legacy.js:4:58)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
```
必須でない引数（パラメーター：設定値）が多くなる場合の処理の定義（使わない引数を定義しない）

# １．設定が必須ではない引数（パラメーター：設定値）をとる処理の定義

これは、クラスとチェーンメソッドを利用して定義するのがよいなと思っています。
GoやNimの場合、構造体をレシーバ変数として定義する関数にあたると思います。

たとえば、CSVを読み込む処理で、区切り文字を変更したり、文字コードを変更したりする場合を考えます。
コードは、PHP(7.4以降）で書いてみます。
具体的な処理実装はせず、インターフェース（呼び出し部分）のみ定義します。

```reader.php

namespace Csv;

class Reader {

 private string path;//ファイルパス
 private string delimiter = ',';//区切文字
 private string charset = 'utf-8';//

 //必ず設定する引数はコンストラクタの引数で設定
 public function __construct(string $path) {
    $this->path = $path;
 }

 public function setDelimitery(string $value) : self { 
  $this->delimiter = $value;
  return $this;//自らの参照を返し、チェーンメソッドにして、別のセッターを呼び出せるようにする。
 }

 public function setCharset(stirng $value) : self {
  $this->charset = $value;
  return $this;
 }

 public function getLines() : array { 
  //ファイルから行を読み込む処理
  return $lines;
 } 

}

```

今回例にした場合だと、getLinesにすべての引数を持たせるのも良いかもしれません。
個人的に、引数が多くなること、また、必ず設定しない引数を定義することは以下のようなデメリットがあると考えます。

:::note alert
・引数が多いのは、その関数の関心が多く、処理が複雑になっている。
・必ず使わない引数を設定すると呼び出し側が悩み、ときに、バグを生むことになる。
:::


引数は、0-2個ですべて必須がベストだと個人的には考えます。それゆえ、任意の設定値が増える場合は、クラスとチェーンメソッドを使った方が、変更しやすく無駄のない呼び出しができると考えます。

では、呼び出しのコードを記載します。

```reading.php

use Csv\Reader;

//文字コードのみ変更する場合。
$lines = (new Reader('任意のファイルパス'))->setCharset('shift-jis')->getLines();

foreach($lines as $line {
 echo $line;
}

//全く変更をしない場合
$lines = (new Reader('任意のファイルパス'))->getLines();

```

上記のように、設定値の要不要に応じて、メソッドを呼び出したり、呼び出さなかったりすることで臨機応変に処理を実行します。
必ず実行する処理の引数の設定は不定になります。

この方がきれいな実行であるし、変更にも強いと思います。

昔、ある現場で、10個以上の引数をとるメソッドがあって、変更が大変なのを経験して、引数が多いのは悪と身にしみて感じました。


# ２．簡易的なビルダーパターン

上記の方法は、デザインパターンでいえば、ビルダーパターンに近いと思います。
ただ、インターフェースを用いた抽象化などは行わないので、厳密にはビルダーパターンと少し違うかもしれません。

https://programming-tips.jp/archives/202206/24/index.html


ビルダーパターンだけではないのですが、デザインパターンは「抽象化」を念頭においた設計が多く、そこまで考えるとややオーバースペックだなと感じるところもあります。

デザインパターンのエッセンスのみを抽出して、簡易的に変更に適応しやすい設計をするのもよいかと思います。


# ３．抽象化とは異なる領域でのクラスの使いこなし

最近、オブジェクト指向への反発から、クラスを使うことを避ける動きもあり、なんでも関数で定義しようとする人もいるかもしれません。ただ、みたように関数の引数を増やすことは読みにくい、呼び出しにくいなどの可読性でデメリットがあります。
また、プログラム改修においても問題を起こすことがよくあります。

オブジェクト指向への反発は、抽象的な設計をしてわかりにくさを招くことをその起因としていると思います。
ただ、それはクラスを使うことと必ずしも同じではありません。
クラスは、ここで見たように、処理レベルでの関心を分離し、クラス全体で複雑な処理を定義するには向いていると感じます。

もちろん、Go、Rust、Nimなどではクラスではなく、構造体をつかって同じような定義ができます。

プログラムは、単純に定義していくこと、呼び出すことで問題を回避できると思います。クラスは無用な混乱を招くものではなく、単純化に役立つ有用な文法であると感じます。
lsync、rsyncでのディレクトリ同期 for WordPress

WordPressを冗長構成するにあたり、ディレクトリ同期を行う必要があり、試行錯誤の結果、lsycd、rsyncの組み合わせでできたので、やり方をメモしておこうと思います。

Amazon Linux 2 on EC2の環境です。

# 必要パッケージのインストール
## Master側での作業

```common_lisp
sudo amazon-linux-extras install -y epel
sudo sed -i -e "s/enabled=1/enabled=0/" /etc/yum.repos.d/epel.repo
sudo yum --enablerepo=epel install -y rsyncd lsyncd
```

## Slave側での作業

```common_lisp
sudo amazon-linux-extras install -y epel
sudo sed -i -e "s/enabled=1/enabled=0/" /etc/yum.repos.d/epel.repo
sudo yum --enablerepo=epel install -y xinetd rsyncd
```

# 通信するためのSSHキーの作成
## Master側でSSHキーを作成する
```common_lisp
sudo su
ssh-keygen -t rsa -N ""
```
## Master側で作成された`id_rsa.pub`の中身をコピーする
```common_lisp
vi /root/.ssh/id_rsa.pub
```

## Slave側にSSHキーをコピー（設置）する
vimでファイルをオープンし、さっきコピーした中身を貼り付ける
```common_lisp
vim ~/.ssh/id_rsa.pub
```
Permissionを変更する
```common_lisp
chmod 644 ~/.ssh/id_rsa.pub
```

# Master側でlsyncd.cofの設定をする
`/etc/lsyncd.conf`の設定は以下のとおりです。

```lsyncd.conf
settings{
    logfile = "/var/log/lsyncd.log",
    statusFile = "/tmp/lsyncd.stat",
    statusInterval = 1,
}

sync{
  default.rsync,
  source = "/var/test/",
  target = "root@{Slave側のLocal IP}::{Slave側のRsyncのModule}",
  init = false,
  delete="running",　
  exclude = {
    ".*"
  },
  rsync = {
    archive = true,
    links = true,
    update = true,
    verbose = false,
    owner = true,
    group = true
  }
}

```

# Slave側でxinetdとrsyncを設定する
## xinetdの設定
```common_lisp
sudo vim /etc/xinetd.d/rsync
```

設定は以下の通り。
```common_lisp
# default: off
# description: The rsync server is a good addition to an ftp server, as it \
#   allows crc checksumming etc.
service rsync
{
    disable         = no
    flags           = IPv6
    socket_type     = stream
    wait            = no
    user            = root
    server          = /usr/bin/rsync
    server_args     = --daemon
    log_on_failure  += USERID
}
```

## rsyncの設定
```common_lisp
sudo vim /etc/rsyncd.conf
```

設定は以下の通り。
```common_lisp
#--------------
# Global options
#--------------
uid           = root
gid           = root
log file      = /var/log/rsyncd.log
pid file      = /var/run/rsyncd.pid
hosts allow   = xxx.xxx.xxx.xx/32 (<= MasterのEC2インスタンスのLocal IP)
hosts deny    = *
dont compress = *.gz *.tgz *.zip *.pdf *.sit *.sitx *.lzh *.bz2 *.jpg *.gif *.png

[wp]
  comment      = rsync server
  path         = /usr/share/nginx/html/xxx
  read only    = false
  exclude      = *.mp
  include      = *.mp30
```

## xinetdを再起動する@Slave
```common_lisp
sudo systemctl restart xineted
```

## lsyncdを起動する@Master
```common_lisp
sudo systemctl start lsyncd.service
```


以上でMasterからSlaveへのディレクトリ同期ができるようになっているはずです。
突然だけどダイスを実装するよ

# 概要と趣旨

タイトルの通り、ダイスを実装するよ。

（2022.10.09追記）
以下の2点を確かめるのが趣旨だよ。

- 同じシード値で生成した乱数列は常に同じ。
- 「シード値を変えれば異なる乱数列が生成される。

コメントにある通りクラス化するメリットのない（むしろ害のある）実装になっているのでおいおい改修していくよ。
とりあえず、今の実装で上に列挙した2点を確かめることは可能。

# 仕様

- シード値は、現在のタイムスタンプをint化した値を使用する。
- シード値を明示的に指定したい場合は、コンストラクタの引数から渡すことが可能。
- 出目の最大値は、ダイスを転がす都度指定する。転がすたびに面数が変わる不思議なダイスだね！
- 出目の最小値は1。
‐ ダイスの面数=出目の最大値で、出目は全て整数値。回りくどい表現だけど「出目が2、4、6、8の4面ダイス」のようなものは想定しない、ってことが言いたい。

# とりあえず実装

こんな感じ。

```Dice.py
'''
Created on 2022/10/08

@author: 芸夢 作郎
'''
import random
import time

class Dice():

    seedValue = None

    def __init__(self, aSeedValue = None):
        if (aSeedValue == None):
            self.seedValue = int(time.time() * 1000)
        else:
            self.seedValue = aSeedValue
        random.seed(self.seedValue)
        return


    def roll(self, aMaxSidesNum):
        ret = random.randint(1, aMaxSidesNum)
        return ret

# （続く）
```

## __init__メソッド

- コンストラクタ。Javaとは異なり、シグネチャの異なる__init__メソッドを複数定義することは不可。
- 第1引数selfは所謂おまじない。「自分自身のインスタンス」を示すキーワードだけど、ここではPythonの基本には触れない。
- 第2引数 aSeedValue でシード値を受け取る。
- 第2引数が指定されない場合は、time.time()関数で取得した現在のタイムスタンプをint型に変換し、シード値として使用する。

## roll()メソッド

- 実際にサイコロを転がすメソッド。
- 引数 aSideNum に、出目の最大値を指定する。
- random.randint()関数で指定した範囲内の乱数を取得し、呼び出し元に返却する。

# テスト

先ほどのソースコードの末尾に、以下を追記する。

```Dice.py
# （続き）

if __name__ == "__main__":

    # シード値に350を指定する
    diceExplicit1 = Dice(350)
    print('① シード値指定1回目／シード値: [{}]'.format(diceExplicit1.seedValue))
    for i in  range(0, 100, 1):
        # 1000面ダイスを100回転がす
        print(diceExplicit1.roll(1000))
    print()

    time.sleep(2)

    # シード値を指定しない
    diceTimestamp1 = Dice()
    print('② シード値にタイムスタンプを使用1回目／シード値: [{}]'.format(diceTimestamp1.seedValue))
    for i in  range(0, 100, 1):
        # 1000面ダイスを100回転がす
        print(diceTimestamp1.roll(1000))
    print()

    time.sleep(2)

    # シード値に350を指定する
    diceExplicit2 = Dice(350)
    print('③ シード値指定2回目／シード値: [{}]'.format(diceExplicit2.seedValue))
    for i in  range(0, 100, 1):
        # 1000面ダイスを100回転がす
        print(diceExplicit2.roll(1000))
    print()

    time.sleep(2)

    # シード値を指定しない
    diceTimestamp2 = Dice()
    print('④ シード値にタイムスタンプを使用2回目／シード値: [{}]'.format(diceTimestamp2.seedValue))
    for i in  range(0, 100, 1):
        # 1000面ダイスを100回転がす
        print(diceTimestamp2.roll(1000))
    print()

    time.sleep(2)

    # シード値に350を指定する
    diceExplicitTheOtherSide = Dice(350)
    print('⑤ シード値指定3回目（面数を変更）／シード値: [{}]'.format(diceExplicitTheOtherSide.seedValue))
    for i in  range(0, 100, 1):
        # 2000面ダイスを100回転がす
        print(diceExplicitTheOtherSide.roll(2000))
    print()
```

実行すると、以下の出力結果を確認できる。

- シード値と最大面数がが同じであれば、乱数の生成結果は同じ（①と③の比較結果）
- タイムスタンプを乱数シードに指定すれば、都度異なる生成結果を得ることができる（②と④の比較結果）
- シード値が同じでも、最大面数が異なれば生成結果は全く異なったものになる（①と⑤の比較結果）

# おわりに

（2022.10.09追記）

コメント欄でもらった指摘（インスタンス変数で使ってるつもりの変数が実はクラス変数だった問題）について、次の記事で不具合を検証したよ。

https://qiita.com/gametsukurou/items/2ebb742ee75c86309879

改修は後日改めて。



以上
UiPath【OrchestratorAPIを使用してStudioまたはRobotからジョブを実行する】

Studioバージョン（2021.10.6）

今回はタイトルのとおりジョブ実行を実装しますが、**ポイントはプロセスに渡す引数**です。フォーラムでも質問している人がいましたが、引数の記述はエスケープシーケンスなど含め複雑で解決していないようでした。このあと回答しておきます。

　・APIリファレンス（ジョブを実行する）
　　https://docs.uipath.com/orchestrator/reference/jobs-requests


【Studioでの実装イメージ】
１．メール本文から「プロセスID」とプロセスに渡す「引数①：employeeNo」「引数②：arg」を取得する。
２．API odata/Releases({key})で１．で取得したプロセスIDを使用してプロセスキーを取得する。
３．API odata/Jobs/UiPath.Server.Configuration.OData.StartJobsでジョブを実行する。実行時には引数①②を渡す。


【Orchestrator上のプロセスの引数】
| Name | Argument | Type |
|:-----------|------------:|:------------:|
| employeeNo       | Input      | String         |
| arg     | Input      | String       |


![プロセスの引数.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2005333/97510d0f-759c-c2c3-66a4-2a5ad42369b2.png)

【メール本文の例】
```body:メール本文の例
　【プロセスＩＤ：45960】
　【従業員番号：98765】
　【arg：TestArgument0】
```
![メール本文.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2005333/dfeb4fdf-5749-4e21-8b31-b8da9d4adc05.png)


```Studio:Studio
　'メール本文から各文字列を切り出す
　　ProcessID = System.Text.RegularExpressions.Regex.Match(CurrentMail.Body, "【プロセスＩＤ：[0-9]+】").Value.Replace("【プロセスＩＤ：","").Replace("】","")
　　employeeNo = System.Text.RegularExpressions.Regex.Match(CurrentMail.Body, "【従業員番号：[0-9]+】").Value.Replace("【従業員番号：","").Replace("】","")
　　arg = System.Text.RegularExpressions.Regex.Match(CurrentMail.Body, "【arg：.+】").Value.Replace("【arg：","").Replace("】","")

　'プロセスキーを取得する
　　「Orchestrator への HTTP 要求」アクティビティ - 「エンドポイントの相対パス」プロパティ
　　 "odata/Releases(" & ProcessID & ")"

　'引数付きでジョブを実行する
　　「Orchestrator への HTTP 要求」アクティビティ - 「エンドポイントの相対パス」プロパティ
　　 "odata/Jobs/UiPath.Server.Configuration.OData.StartJobs"

　　「Orchestrator への HTTP 要求」アクティビティ - 「JSONペイロード」プロパティ
　　 "{  ""startInfo"": {    ""ReleaseKey"": """ & jsonBody("Key").ToString & """,    ""Strategy"": ""Specific"",    ""RobotIds"": [29254], ""InputArguments"": ""{\""employeeNo\"":\""" & employeeNo & "\"",\""arg\"":\""" & arg & "\""}"" }}"

```

[サンプルソースはこちら](https://github.com/bus-masapiyo/UiPath_OrchestratorAPI_StartJobs)

:::note 

 【今回のコメント】

　・引数は色々チャレンジしてやっと解決しました。
　・次回はStudioXでも同じような実装の記事を書こうと思います。
　
:::
僕の高速かつ可読性の高いSQL（結合編）

# 経緯
「弊社のエンジニアであればSQLの軽いチューニングはできて当然」というレジェンドエンジニアのKさんの言葉を受け下記の本を読みましたのでそのアウトプット＆共有ができればと。

[SQL実践入門──高速でわかりやすいクエリの書き方 ](https://www.amazon.co.jp/SQL%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80%E2%94%80%E2%94%80%E9%AB%98%E9%80%9F%E3%81%A7%E3%82%8F%E3%81%8B%E3%82%8A%E3%82%84%E3%81%99%E3%81%84%E3%82%AF%E3%82%A8%E3%83%AA%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96%B9-WEB-DB-PRESS-plus/dp/4774173010)

# 筆者について
最近、仕事用の服につなぎを購入しためんどくさがりエンジニア。
当社は私服勤務OKなんですが、服を選ぶのが面倒なのでつなぎを買いました。
ただアメリカから輸入したものなので、足が長すぎて今は裾上げ中です。
SQLをカリカリにチューニングみたいな経験はないので、誤りがあれば教えてください。

# 当記事の内容
[SQL実践入門──高速でわかりやすいクエリの書き方 ](https://www.amazon.co.jp/SQL%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80%E2%94%80%E2%94%80%E9%AB%98%E9%80%9F%E3%81%A7%E3%82%8F%E3%81%8B%E3%82%8A%E3%82%84%E3%81%99%E3%81%84%E3%82%AF%E3%82%A8%E3%83%AA%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96%B9-WEB-DB-PRESS-plus/dp/4774173010)の第6章に即した内容になります。
テーマは **結合** です
可読性の高いSQLという記事タイトルの割に今回はあまりSQLを改善するような内容ではないです。。。

# 結合アルゴリズム
だいたいのDBMSは以下の3つを基本的にサポートしてます。
1\. Nested Loops
2\. Hash
3\. Sort Merge

## Nested Loops
### 処理順序
![NestedLoops.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549748/5dfc073a-9af2-9227-67f0-6d52eeb991d3.png)
1\. 駆動表（Table A）を1行ずつループ。
2\. 駆動表の1行に対して内部表を1行ずつループして、結合条件に合致すれば結果を返却。
3\. 1,2を駆動表の全行に対して繰り返す。


### 特徴
* 処理時間は行数に比例する。（駆動表の行数×内部表の行数）
* 1つのステップで処理する行数が少なく、メモリの消費量が他の結合アルゴリズムに比べると少ない。
* （どのDBMSでサポートしてる。）

### Nested Loopsでパフォーマンス改善するためには
SQLのパフォーマンスを改善する際のキーワードとして **駆動表を小さくする** というのがありますが、これはNested Loopsの性能において非常に大きな意味を持つキーワードになります。
駆動表の処理順序から考えると結局、駆動表と内部表の行数の掛け算なので、駆動表の方が小さくてもパフォーマンスに影響はなさそうですが、実際は、、、
 **駆動表を小さくする** に加えて  **内部表の結合キー列にインデックスが付与されている** という暗黙の前提があれば、Nested Loopsの性能は大きく改善されます。

![NestedLoopsIndex.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549748/7c43e7ea-7f7f-ca59-9070-1b3b1e89f7ad.png)
理由は単純にindexを挟むことで内部表を全行スキャンしなくても内部表を絞り込めるためです。
 **駆動表を小さくする × 内部表の結合キー列にインデックスが付与されている**
くり返しになりますがコチラがNested Loopsのチューニングの基本になります。
 ただ、インデックスを挟んでもインデックスに対して内部表で大量のレコードがヒットしてしまうとインデックスを挟んでも想定のパフォーマンスはでなくなってしまいますので注意が必要です。


## Hash
### 処理順序
![Hash.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549748/2b4efccb-105f-70b3-96ac-d9979f94a98f.png)

1\. オプティマイザが小さいと見積もったテーブルをスキャン
2\. 結合キーに対してハッシュ関数をかけてハッシュテーブルを生成
3\. もう一方の大きいテーブルをスキャンしてハッシュ値を生成して一致するかチェックして結合

### 特徴
* ハッシュテーブル生成のためにメモリを消費する。（Temp落ちしたら速度がガクっと落ちる）
* 等値結合でのみ使用されるアルゴリズム。
* 結合対象の両テーブルをフルスキャンする必要がある。

## Sort Merge
### 処理順序
![SortMerge.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549748/60e86a4f-97f7-0bd6-21f0-ffe7f36cd3a6.png)
1\.結合テーブルをソート
2\.もう1つの結合テーブルもソート
3\.ソートしたテーブル同士を結合

### 特徴
* Hash同様、メモリを多く消費する。基本的には両テーブルをハッシュ化するためHashよりも多くメモリを消費する。
* Hashと異なり同値以外の結合でも利用可能。（意外とテーブルの結合って同値以外に>、<、>=、<=とかでできるって知らない人いますよね。）

# 当章を読んで
SQLをチューニングする際に言われるキーワードはたくさんあります。
* 結合では駆動表を小さく
* 結合条件の左辺では演算は行わない
* like検索では前方一致になるように
などなど、、、
*今回は駆動表は小さく* の理由を説明しておりましたが、闇雲に従っただけではなく意図をりかいすることは大切だなと思いました。
[python] pandasでloc, iloc, at, iat を用いた行、列の取得

# はじめに
pandas を用いてデータフレームを扱う場合、範囲を絞ることによって必要なデータのみを得ることが必要である
今回は`loc, iloc, at, iat`を用いて必要な範囲のみを指定し、範囲を絞ることを紹介する。

# 環境
window 10

```python
import sys
print(sys.version)
print(pd.__version__)
```
```
3.7.8 (tags/v3.7.8:4b47a5b6ba, Jun 28 2020, 07:55:33) [MSC v.1916 32 bit (Intel)]
1.3.5
```
# Code

```python
import pandas as pd

df = pd.read_excel('./data.xlsx', index_col = 0)
df
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/eeed5176-eac9-d58a-e6e0-6d81f852f196.png)



## loc, iloc
データフレームの行もしくは列を取得するためには`loc、iloc`を利用する。

行名、列名を用いてるときは -> `loc`
行もしくは列のindexを用いるときは indexの"i"を用いて -> `iloc`


### loc
`'Kobayashi'`の行を取得する
```python
df.loc[['Kobayashi'],:]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/bfd95cf0-528e-75c9-5cdf-114018a2dd01.png)


`'Point','ambition'`の列を取得する
```python
df.loc[:,['Point','ambition']]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/2a15f1ef-171f-7940-72dc-fd57414a4121.png)


`'Kobayashi', 'Aizawa'`の行、`'Point','ambition'`の列を取得する
```python
df.loc[['Kobayashi', 'Aizawa'],['Point','ambition']]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/b3a3598a-e864-ca39-bc80-ad3faa725845.png)



### iloc
`1,2`番目の行を取得する
```python
df.iloc[[1,2],:]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/48bf7280-4ef9-ff38-5173-2aad63dfea8f.png)


`1,2`番目の列を使用する
```python
df.iloc[:,[1,2]]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/df0e1612-1476-ec5a-915e-67b5330cdbfa.png)


`1`以上の行、`1,2`の列を取得する
```python
df.iloc[1:,[1,2]]
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/94643d09-0e8f-7d17-3b24-cbb45419367e.png)


# at, iat
`at, iat` は特定の行、列に属する値を取得する

### at
行が`'Tanaka'`, 列が`'Point'`の値を取得する
```python
df.at['Tanaka','Point']
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/ac9aea6a-cf46-e46b-8c67-44247a8eafb7.png)

### iat
行が`1`番目, 列が`1`番目の値を取得する
```python
df.iat[1, 1]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/ac9aea6a-cf46-e46b-8c67-44247a8eafb7.png)


# まとめ
以上のように、必要に応じて範囲を絞ることによって必要とするデータのみを得ることができる


# 関連記事


https://qiita.com/junzai/items/4b60bc51d342a79d768e
 
https://qiita.com/junzai/items/fd626f8a71a15cabd91a

https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.loc.html
【SwiftUI】文字色を背景色の反対色にする

# はじめに
背景色が動的に変更されるアプリだと背景色と同化して文字が見えなくなる問題が発生します。
そんな問題を発生させないメソッドを見つけたので紹介します。

# サンプルアプリ
![Simulator Screen Recording - iPhone 14 Pro - 2022-10-08 at 20.36.58.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/f427e221-883d-99a1-9251-87b45c1e077f.gif)

# 実装
```diff_swift
import SwiftUI

struct ContentView: View {
    @State var percentage: CGFloat = 100
    var body: some View {

        VStack(alignment: .center) {

            batteryShape.overlay(batteryText)

            Slider(value: $percentage, in: 0...100)
                .frame(width: 250)
        }
    }

    var batteryText: some View {
        Text("\(Int(percentage))")
            .font(.system(size: 70, weight: .black))
            .foregroundColor(.white)
+           .blendMode(.difference)
    }

    var batteryShape: some View {
        ZStack(alignment: .center) {
            RoundedRectangle(cornerRadius: 15)
                .stroke(Color.strokeColor, lineWidth: 6)
                .frame(width: 250, height: 120)

            RoundedRectangle(cornerRadius: 10)
                .frame(width: 230 * (percentage / 100), height: 100, alignment: .leading)
                .alignmentGuide(HorizontalAlignment.center) { _ in 115 }
        }
    }
}
```

:::note info
**ポイント**
`.blendMode(.difference)`
これを指定することによって背景色の反対色になる
:::

# おわり
iPhoneのバッテリー表示を今回のサンプルアプリみたいにしてほしい、、、笑
特定環境下でArduinoのシリアルポートにアクセスできないときのメモ

# 概要
Arduinoにシリアル通信させるプログラムはArduino IDEで書き込めたけど、Arduino IDE以外からシリアルポートにアクセスできなくなった対処の話。

類似事例が無いか軽く調べてみたけど引っかからなかったので需要があるんじゃないかと記録する。


# 状況発生環境
検証のための再現環境構築はしていない。シリアルポートがらみの主要登場人物から推定。
- Windows10
- Arduino IDE2.0.0
- Keysight IO Libraries Suite2022(多分主犯）


# 状況
Arduinoにシリアル通信でメッセージを送ってリレー制御したり、Arduinoの動作状態を返信するプログラムを書いたときに発生。

Arduino IDEでプログラムを書き込んで、Arduino IDE付属のシリアルモニタでメッセージを送って期待通りの動作をしていることを確認。

で、上記Arduinoを含めて複数の測定器を連動させたプログラムを作る段階で問題発生。

# 不具合現象(シリアルポートが開けない)
デバイスマネージャー上でArduinoのシリアルポートが認識されているにも関わらず、シリアルポートを開こうとするとエラーが出る。
色々試したけど例としてpyvisaで、こんなコードを書いてエラーが出る

```python
import pyvisa
rm = pyvisa.ResourceManager()
resource_list = rm.list_resources()
print(resource_list)
('ASRL1::INSTR','ASRL2::INSTR', 'GPIB0::12::INSTR') 
# イメージとしてpyvisa公式ページのサンプルコード結果修正引用
# ASRL2::INSTR相当が制御をかけたいArduinoのシリアルポート
inst = rm.open_resource('ASRL2::INSTR') # <-ここでエラー発生
```
試したのはほかにも
- pyserial ほぼ同様のところでエラー発生
- TeraTerm シリアルポートを認識しない
- PCのArduinoを刺すUSBポートを変更してもダメ
- Arduino IDEのシリアルモニタでは問題無く動く


# 原因と対処

どうもKeysight IO Libraries SuiteがArduino IDEのシリアルポートを勝手に占有していた模様。
その割にpyvisaでアクセスができないのはKeysight Connection Expert上でのシリアルポートを使用するためのボーレート等の設定が不足していたから。下記画面でシリアルポートの設定を行ったところ、前述のコードがエラーを吐かずに正常に走るようになった。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527090/91073758-463b-f6b1-270b-5d791ac3129b.png)

# 最後に

ちょっとKeysight IO Libraries Suiteの行儀が悪い・・・でも、GPIBがらみの制御では欲しいからアンインストールもできない困りもの。

あと、なんでArduino IDEは普通にアクセスできるのかが謎である。
【Linux】コマンドのグルーピング

## グルーピング方法
`(command)`または`{ command; }`とすることでコマンドをグルーピングできます。

`(command)`はサブシェルで実行されます。
以下のように実行してもディレクトリは移動しません。
```
(cd ..) 
```

`{ command; }`はカレントシェルで実行されます。
以下のように実行するとディレクトリが移動します。

```
{ cd ..; }
```
また記述する際に`{`の後にスペースが必要であることとコマンドの最後に`;`を記述するか改行する必要がります。
Denoでfirebase-adminが使えるか確認した

# 追記（2023/4/29、deno@1.33.0）

:::note info
deno v1.33よりfirebase-adminが使えるようになりました！
:::

2023年4月28日にdeno v1.33がリリースされました🎉

https://deno.com/blog/v1.33#improvements-to-npm-and-node-compatibility

上記記事によると、`crypto.getCurves`が実装された様子

ということで使ってみたところ、無事使えました！

これでやっとfirebaseを管理者権限でdenoから扱えるようになりましたね(^▽^)/


# 記事本文


Denoでは最近のアップデートでimport時に`npm:`とつけることでNodeモジュールをインポートできるようになりました。

私はあるプロジェクトで`firebase-admin`をDenoから利用したいのですが、まだNode.jsのcryptoモジュールが完全にポリフィル出来ていないようで実行できません。
（`crypto.getCurves`が実装されてない？）

以下の確認コードを実行して上手く使えるようになったらDenoで`firebase-admin`を使えそうです！


## 確認コード

```typescript:main.ts
import { getAuth } from "npm:firebase-admin/auth";
getAuth();
```

## 結果（2023/3/17、deno@1.31.2時点）
```
PS C:\Users\kamekyame\Documents\gh\kakomimasu\server> deno run -A test.ts
error: Uncaught Error: Not implemented: crypto.getCurves
    at notImplemented (ext:deno_node/_utils.ts:7:11)
    at getCurves (ext:deno_node/internal/crypto/util.ts:107:5)
    at Object.<anonymous> (file:///C:/Users/kamekyame/AppData/Local/deno/npm/registry.npmjs.org/jose/2.0.6/lib/r
egistry/ec_curves.js:5:5)                                                                                           at Object.<anonymous> (file:///C:/Users/kamekyame/AppData/Local/deno/npm/registry.npmjs.org/jose/2.0.6/lib/r
egistry/ec_curves.js:23:4)                                                                                          at Module._compile (ext:deno_node_loading/02_require.js:745:34)
    at Object.Module._extensions..js (ext:deno_node_loading/02_require.js:778:10)
    at Module.load (ext:deno_node_loading/02_require.js:656:32)
    at Function.Module._load (ext:deno_node_loading/02_require.js:513:12)
    at Module.require (ext:deno_node_loading/02_require.js:678:19)
    at require (ext:deno_node_loading/02_require.js:818:16)
```

<details>
<summary>過去の結果</summary>

## 結果（2022/10/08、deno@1.26.1時点）
```
error: Uncaught Error: Not implemented: crypto.getCurves
  throw new Error(message);
        ^
    at notImplemented (https://deno.land/std@0.159.0/node/_utils.ts:25:9)
    at getCurves (https://deno.land/std@0.159.0/node/internal/crypto/util.ts:60:3)
    at Object.<anonymous> (file:///C:/Users/kamekyame/AppData/Local/deno/npm/registry.npmjs.org/jose/2.0.6/lib/registry/ec_curves.js:5:5)
    at Object.<anonymous> (file:///C:/Users/kamekyame/AppData/Local/deno/npm/registry.npmjs.org/jose/2.0.6/lib/registry/ec_curves.js:23:4)
    at Module._compile (deno:ext/node/02_require.js:719:36)
    at Object.Module._extensions..js (deno:ext/node/02_require.js:752:12)
    at Module.load (deno:ext/node/02_require.js:636:34)
    at Function.Module._load (deno:ext/node/02_require.js:493:14)
    at Module.require (deno:ext/node/02_require.js:658:21)
    at require (deno:ext/node/02_require.js:789:18)
```

</details>

## 補足

esm.sh というサービスもありますが、deno用にバンドルするのに、nodeの機能を`std/node`で補っている（`npm:`を使ってimportするときと同じ仕組み）ので、esm.shを使っても同じエラーに遭遇します。
jQueryの応用、開閉式ブロック。

開閉式ディブ、dl=Div List, dt=Div Title, dd=DIv Descriptionによるたっぷ操作。　
```
// Div list 1
<dl id="panel1">
    // dt1
    <dt>Title 1</dt>
    <dd>Description of letters</dd>
    // dt2
    <dt>Title 2</dt>
    <dd>Description of letters</dd>
</dl>
<script>
// $(document(function(){ の短縮形
$(function(){
    // dd close
    $('#panel1 dd').hide();
    // A dt clicked
    $('#panel1 dt').click(function(){
        // Set d is clicked dt's children of dd
        var d = $('+dd', this);
        if(d.css('display') === 'block'){
            d.slideUp(1000);
        } else {
            d.slideDown(1000);
        }
    });
});
```
タグ操作だけで特定のdd を閉じたり開いたりする、ためのthisプロパティー。
振り返り時間の雑談っていらなくないですか？

### はじめに

* 筆者は初めてアジャイルの開発でスクラムを経験。3ヶ月が経つ。

* 今回チーム内で出た意見を元に、良い気づきを得ることができたので記事にまとめました。

        ★フルリモート環境
        ★バックエンドとフロントエンドでチームが分かれている
        ★私を含む新規参画者はスクラム初心者
        ★バック、フロントそれぞれスプリントの振り返りが終わった後、
          スクラムチーム全員で共通の振り返りという名の雑談タイムがある。（30m～）


### 雑談の時間っていらなくないですか？

この議題があがり、スクラムチームの意見をいただきました・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543815/e38c7ab8-a610-e128-1ed7-dc792831b59c.png)

最終的な投票結果では、現状のままで良いという結論に至りましたが
* 雑談のメリット
* 改善案
* 新しい手法の提案

色んな気づきを得ることができたので記していきたいと思います。


### この議題が生まれた背景

そもそも、開発状況が芳しくない。という所に
新規参画者の方が目をつけてくださいました。

『進捗率があまり良くない状況の中でスクラムイベントや、話し合いに欠ける時間が
長すぎるんじゃないか、雑談に時間を割いていてもいいのか？』

『毎週30m～1h（各チーム内振り返り含むと1時間以上の時もあったかも？）掛ける必要があるか？』

という議題が挙げられました。


ごもっともです・・・
『この意見は正直ごもっともです。』
（でも、、楽しいからやりたいなぁ無くなるのはやだなぁ:joy:）
と私は思ってましたｗｗ

### さっそくMIROで意見を募る

少し前から、議論が白熱しMT時間が長くなったり、話が脱線したりと
時間がかかってしまう事がバックエンドチーム内で問題として挙げられていました。

そのための改善案が
* その場で話し合うのではなく、MIROを使って付箋で意見を募る
* 大体１週間と期日をきめ、意見をまとめる人（1,2名程）が付箋を整理し共有する

今回もこの方法でスクラムチーム全体に意見を募りました！

### 実際の意見や改善案たち

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543815/b69cde27-1496-6273-2d90-d9bbbc7f97ad.png)

* 皆、共有の振り返りはやりたい！ってゆう意見が圧倒的に多かった
* やるからには改善案として以下が挙げられた
    * 時間短縮
    * 任意参加
    * 隔週(今回、隔週にはしなかった）

これみて皆もやりたがってるんだ～
と思って正直ホッとしました:kissing_closed_eyes:

そして、このMIROでの意見出しは匿名で書けるし、
普段意話すのが苦手な人も平等に意見出せるからいいなと改めて感じました！

### 今回一番の気づき、雑談＞振り返りぐらい雑談は大事

『共通の振り返りは楽しいからこれからも継続したいな』
としか考えてなかったけど、実は雑談ってメリット沢山あるってことを知りました！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543815/61052c9b-9bbb-3113-253c-37b4aa115723.png)

#### 雑談のメリットたち

MIROに載せてくださっていた記事を抜粋してみました

:::note info

アジャイルウェアの仕事は、**とにかくすぐ行動、スピードと品質に妥協しない**
　　　　　　　　↓　　↓　　↓
**早い段階で気軽に相談**することが重要
　　　　　　　　↓　　↓　　↓
**雑談**こそ、それ（早い段階で気軽に相談すること）を実行しやすい環境を作る

:::

:::note info

すぐに**話かけやすい雰囲気、関係性**をつくることができる
リモートワークでも**人との繋がり**を感じられる
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543815/91cb7294-5c7a-67d5-7481-a499bdaa9985.png)

https://agileware.jp/blog/culture/2021_0325/


:::note info
**雑談は心理的安全性の確保のために重要**
:::

:::note info
話すことへの抵抗感が下がる、メンバーへの慣れ
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543815/a9c5d4c3-cec2-9cc0-5e54-b85f1ff8d15f.png)

https://www.agile-studio.jp/post/recommendation-for-small-talk




#### ちなみに新しい手法導入の案もあったけど・・

 振り返りの手法を変える案で、リーンコーヒー導入もとても良いなと思ったのですが、今回議題に上がった背景が『時間かけすぎでは？』という所に焦点を当てていたため、個人的には更に時間をかけてしまうのではという懸念がありました。
でも雑談のメリットを考えるとこれも凄くいいなと思いました！

https://symphonict.nesic.co.jp/tech-blog/205/

### 終わりに

* 結果、現状のままとなったが元々時間はもっとかかっていた（30m以上は絶対かかってた）のでダラダラ長時間やらない。時間短縮するという共通の認識が持てたことはよかった。
* 何のために振り返りという時間があるのかの目線合わせができた。
* 雑談のメリットを知ることができた。
* ただ、振り返りは「進捗」を改善する場でも あるので、改善は今後も必要。


↓他にもチーム内で改善できたことをまとめた記事はこちらです:writing_hand_tone2:

https://qiita.com/yamamoto_anna/items/9532dbdd660d7b08e35f

最後までお読みいただきありがとうございました♩
障害やQAからもテストを書けよと言う話

あるプロジェクトで、障害やQAの後にもテストを書くと、安心感が増すなと思ったのでまとめたいと思います。


# テストはないがQAはあるプロジェクト
少し前に、副業でバックエンドの開発をしていました。
プロダクトの性質上、品質保証が重要なためQAメンバーやリリースフローはありますが、肝心のコードはテストが何もなく目視チェックでデプロイしQAメンバーが保証すると言う状態になっていました。

問題は、テストがないため頻繁にバグが再発しQAメンバーが疲弊していくことです。

テストで動作を保証してないので、バグ修正してデプロイしても、罰のバグが再発することに気がつかないことが頻繁に起きました。
そしてそのバグを発見するのは大体QAなのです。

このため、エンジニアとQAでコミュニケーションが増えるし、QAは同じバグを報告することが延々と続くことになりました。



担当していたプロジェクトは短納期のだったので、テスト対象は適切に選択する必要がありました。
その上、慣れてない言語だったのでテストの導入にも時間がかかり、全てのテストケースをカバーするのは難しい状況でした。




# QAの結果からテストすればいいんじゃね？
ふと思ったのは、QAのテストが全てpassすればよく、QAの全てでユニットテストを書く必要はありません。

であれば、QAをさっさと通して結果からテストを追加していけば、一度起こったバグはテストで保証されるので効率的なのでは？と考えました。

なので、以下の方法を取りました。
* データ保存などクリティカルな異常系や、動かないと困る正常系のみユニットテストを記述
* できた段階でQAへお願いする
* QAのバグ報告からテストの設計をし直し、ユニットテストを追加する
* QAのテストケースを全てpassした時点でQAを終了する


これで、一度起こったバグはテストで保証されていくので、数を重なるたびに信頼度は高まっていきます。
エンジニアも、影響範囲やバグの原因を絞り込むのが容易になるので、修正速度が上がっていきます。

と言うわけでこれで回してみました。

# 実際の運用
結論から言うと結構うまくいきました。
一度直したバグを潰せていることは、後戻りがないということなので、QAとエンジニアで同じバグに悩むこともなくな精神的に安定して作業が行えるようになりました。

QA中に、エンジニアがリファクタするときも、テストで補償されてるので安心感があります。



# 最後に
このアプローチはQAに限らず、障害にも使えるなと感じました。
TDDの文脈では回帰テストと呼ばれるそうです。  
ポストモーテムのTODOに入れるなどしていきたいです。

それでは良きテストライフを
Ubuntu で ROCm(amdgpu) と CUDA(nvidia) の混在での運用のメモ

## 背景

ROCm(AMD GPU)もそれなりに安定して動くようになった. けどまだまだ CUDA も使いたいときや, ROCm での動作がおかしいときに CUDA で実行確認したいときがある.

## 構成

Ubuntu 20.04 or 22.04 とします.

以前だとなんかうまく同時認識されなかったりしましたが,
ROCm 5.2 以降あたりだと, 特には問題なく動くような気はしています.

- Intel z590 マザー
- AMD X570 マザー

の両方で動作確認しました. より安定を求めるなら x299, x399 あたりのワークステーション系がいいかもしれません


### ROCm pytorch は Docker で

pytorch で両 GPU を同時に使うのは無理でしょう.

conda で環境切り替えでの対応でもよいかもですが, 

https://pytorch.org/get-started/locally/

でのインストールでは ROCm バージョン古いままなので, ROCm のほうは Docker で運用がよいと思われます.

https://hub.docker.com/r/rocm/pytorch/tags
android appでOkHttpを使ってapiをたたくためにやったこと

# 前置き
既存の自作webアプリ向けのbackendを
新規開発するandroidアプリからも利用したかった。
やり方を調べるのに時間がかかっためここにまとめる。

# 前提条件
開発環境は以下である。
| OS | macOS Monterey12.6 |
|:-:|:-:|
| IDE | IntelliJ IDEA 2022.2.2 |
| 言語  | kotlin |
| ビルドツール | gradle |

# 追記箇所
実際に動作が確認できるまでに追記した箇所を示す。

## build.gradle.kt
依存関係の追記。
pathは公式HPから参照した。
https://square.github.io/okhttp/#releases
```gradle
implementation("com.squareup.okhttp3:okhttp:4.10.0")
```

## AndroidManifest.xml
インターネットへのアクセスを許可する設定を追記する必要がある。
```xml
<uses-permission android:name="android.permission.INTERNET" />
```

## MainActivity
公式HPのSampleを参照しつつ追記した。
http通信のような処理は非同期でないと怒られるようなのでThreadを使用している。
また、URLは適宜叩きたいものに変更すること。
https://square.github.io/okhttp/#get-a-url

```kotlin
class MainActivity : FragmentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Thread {
            GetHoge().run("https://hogehoge")
        }.start()
    }

class GetHoge {
    private val client = OkHttpClient()

    @Throws(IOException::class)
    fun run(url: String): String? {
        val request: Request = Request.Builder()
            .url(url)
            .build()
        client.newCall(request).execute().use { response ->
            return response.body?.string()
        }
    }
}
```

# 最後に
日本語検索ではokhttpは3でないものの記事しかでてこなかった。
おそらく情報が古い。
やはり公式を見にいくことが大事。

また、個人的にはkotlinですべて書いていきたいものの、
javaで書かれたものが大半で置き換え作業に苦戦した。
IBM® Log Analysisのセッティング編

# 記事の内容
本記事ではIBM® Log Analysisのライトプラン（無料）を使用するまでの流れを記したものである。

# IBM Log Analysis
IBM Log Analysisを使用すると、IBM Cloud内のオペレーティング・システム・ログ、アプリケーション・ログ、およびプラットフォーム・ログを管理できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/c720ee25-4e38-2d88-a274-b7971847c9a2.png)

IBM Log Analysisは、リアルタイムでのログのトラブルシューティングによって問題を診断し、問題を特定することができる。その際に、アラート通知を、例えば、EメールやSlackに送信することで、素早く対応できるようになり、被害を最小限にとどめることが可能である。

IBM Log Analysisは、以下のサポートされているいずれかのIBM Cloudロケーションで作成できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/1b3b9f28-a73d-d3a1-f141-875d8ddb48d7.png)

アプリケーション自体の出力をモニターすることができるIBM Log Analysisに加え、アプリケーションに影響を与えるイベントを監視するIBM Cloud Activity Tracker with LogDNAを利用することで、IBM Cloudを包括的に監視することができる。

さらに、IBM Cloud Monitoring をセットアップすることで、パフォーマンスと正常性をモニターすることができ、IBM Cloudの可観測性を高めていくことができる。

### 記事の前提
IBM Cloud アカウントを持っていない場合は、IBM Cloud アカウントを登録してください。


## IBM® Log Analysisのセッティング
IBM Cloud アカウントにログインする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/0be8282f-e859-f720-2427-bd8731a0596c.png)

「カタログ」をクリックする。 IBM Cloud で使用可能なサービスのリストが開く。
「IBM Log Analysis」をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/ea3dbbca-fd15-ab2f-6faf-08e8ed85ccc9.png)

サービス・インスタンスのリージョンを「東京」で選択します。
無料で作成する場合は、「ライト」サービス・プランを、有料で使用する場合は必要に応じたプランを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/e32bed8c-832e-7151-64b4-34b64728fa30.png)

作成されると以下のような画面が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/eb646254-5185-4065-e192-4ccdb6976b8a.png)


Logを収集するソースに応じて、設定方法が異なる。今回は、Db2 on Cloud、つまり、IBM Cloudサービスのログを収集する。

参考として、以下にログ・ソースごとのステップを記載する。
|ログ・ソース  |ステップ  |
|---|---|
|IBM Cloud サービス  |[IBM Cloud プラットフォーム・ログの構成](https://cloud.ibm.com/docs/log-analysis?topic=log-analysis-config_svc_logs)  |
|Kubernetes クラスター  |[Kubernetes クラスターからのログの収集と分析](https://cloud.ibm.com/docs/log-analysis?topic=log-analysis-kube)  |
|Linux  |[Linux 環境からのログの収集と分析](https://cloud.ibm.com/docs/log-analysis?topic=log-analysis-ubuntu#ubuntu)  |
|Windows サーバー  |[Windows Server システムからのログの収集と分析](https://cloud.ibm.com/docs/log-analysis?topic=log-analysis-windows_serv)  |
|Cloud Foundry  |[Cloud Foundry リソースからのログの収集と分析](https://cloud.ibm.com/docs/log-analysis?topic=log-analysis-monitor_cfapp_logs)  |

IBM Cloudのサービスのログを取得するため、リージョン内のロギング・インスタンスを構成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/5569d846-9fc7-971a-72c0-5fc8b5887c64.png)

「プラットフォーム・ログの構成」を選択し、「リージョンでインスタンスをフィルター」を「東京」、「リージョン内のインスタンス」を「IBM Log Analysis with LogDNA」を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505349/b7f892a1-43a8-f55b-f9bf-4c01cc814565.png)

これにて、「プラットフォーム・ログの構成」を行うことができ、IBM Cloudのサービスのログをダッシュボードから確認することができる。
【BigQuery】GEOGRAPHY型でGroupByしたいときはANY_VALUE()が使える

GEOGRAPHY型は集計列に指定できないので、ちょっと困ったことになることがあります。

### 検証用データ
例えばこんな風に、日付、位置、売上額が入ったデータを受け取って、そこから日毎の売上合計を算出したかったとします。
```sql
WITH salesAmount AS (
  SELECT *
  FROM
    UNNEST([
      STRUCT(DATE'2022-04-01' AS date, ST_GEOGPOINT(0, 0) AS point, 1000 AS amount),
      STRUCT('2022-04-01', ST_GEOGPOINT(0, 0), 500),
      STRUCT('2022-04-02', ST_GEOGPOINT(0, 1), 10000),
      STRUCT('2022-04-03', ST_GEOGPOINT(1, 1), 2000)
    ])
)

SELECT * FROM salesAmount
```

#### 実行結果
|date|point     |amount|
|----|----------|-----:|
|2022-04-01|POINT(0 0)|1000|
|2022-04-01|POINT(0 0)|500|
|2022-04-02|POINT(0 1)|10000|
|2022-04-03|POINT(1 1)|2000|

日毎に売り場を変えるので、 `point` は日付ごとに一意になります。

### GROUP BYを試す
ここで、 `date` と `point` で `GROUP BY` しようとすると…
```sql
SELECT 
  date,
  point,
  SUM(amount) AS totalAmount
FROM salesAmount
GROUP BY date, point
```

こんなエラーメッセージが表示されます。

:::note alert
Grouping by expressions of type GEOGRAPHY is not allowed
:::

GEOGRAPHY型の項目は `GROUP BY` に設定できないのだそう。

### `ANY_VALUE()` が使える
こんな場合は、 [ANY_VALUE()](https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate_functions?hl=ja#any_value) を使うのが便利です。

```sql
SELECT 
  date,
  ANY_VALUE(point) AS point,
  SUM(amount) AS totalAmount
FROM salesAmount
GROUP BY date
```

#### 実行結果

|date|point|totalAmount|
|----|-----|----------:|
|2022-04-01|POINT(0 0)|1500|
|2022-04-02|POINT(0 1)|10000|
|2022-04-03|POINT(1 1)|200|
【React】 n秒後に処理を実行する

# はじめに
まだまだ不完全なコードですので、参考にはならないと思います。
「こうしたらできる」などのコメントお待ちしています。
よろしくお願いいたします。

コメントにて
@honey32 さんからわかりやすい説明付きでコードを頂いていますので、
困っている方はそちらを参考にしてください！

# やりたいこと
ダイアログに入力した文字を画面に表示したい。
最後に入力してから2秒後にダイアログを閉じ、その時点の文字列を画面に表示したい。
# 課題
・画面に文字列が表示されない
・想定している秒数で画面が閉じない

# コード
```App.tsx
import * as React from 'react';
import Button from '@mui/material/Button';
import DialogTitle from '@mui/material/DialogTitle';
import Dialog from '@mui/material/Dialog';
import Typography from '@mui/material/Typography';
import { DialogContent, TextField } from '@mui/material';
import { useState } from 'react';

export interface SimpleDialogProps {
  open: boolean;
  value: string;
  onClose: (value: string) => void;
}

function SimpleDialog(props: SimpleDialogProps) {
  const { onClose, value, open } = props
  const [input, setInput] = useState<string>('')
  let count: number = 0

  const handleClose = () => {
    onClose(value);
  };

  const timer = () => {
    const countUp = () => {
      count++
    }
    const intervalId = setInterval(() => {
      countUp()
      if (count > 2) {
        clearInterval(intervalId)
        setTimeout(() => {
          setInput(props.value)
          console.log('input:' + input)
          handleClose()
        }, 100)
      }
    }, 1000)

  }
  const getInput = (e: any) => {
    setInput(prev => prev + e.key)
    timer()
  }

  return (
    <Dialog onClose={handleClose} open={open}>
      <DialogTitle>Input here</DialogTitle>
      <DialogContent>
        <TextField
          value={input}
          onKeyDown={getInput}
        />
      </DialogContent>
    </Dialog>
  );
}

export default function SimpleDialogDemo() {
  const [open, setOpen] = useState<boolean>(false)
  const [value, setValue] = useState<string>('')

  const handleClickOpen = () => {
    setOpen(true)
  }

  const handleClose = (value: string) => {
    setOpen(false)
  }

  return (
    <div>
      <Typography>inputValue:{value}</Typography>
      <Button variant="outlined" onClick={handleClickOpen}>
        Open Dialog
      </Button>
      <SimpleDialog
        value={value}
        open={open}
        onClose={handleClose}
      />
    </div>
  );
}
```
SuiteCRMを入れてみた

CRMの構築が必要になってきたので色々とOSSを調べてSuiteCRMを試しに使ってみることにしました

# DockerでSuiteCRMをインストール
DockerImageがあったので早速利用。こういう時Dockerは便利ですね〜

https://hub.docker.com/r/bitnami/suitecrm/#!

# 日本語化を実行
Dockerを立ち上げてみると全て英語・・・
ってことで日本語化モジュールをダウンロードしてインストール

https://docs.suitecrm.com/admin/installation-guide/languages/install-a-new-language/

これでサクッと準備完了です
いやー、簡単
便利な世の中になったなぁ

# 今後
さてここから使いやすいようにカスタマイズしていこうと思います

最終的にはAWS上にコンテナとして反映させるのが理想
データベースもQuickSite用にレポーティングできるようなアーキテクチャにしたいと思ってます