OmniAICreator/Qiita-1.07M huggingface dataset:
Scoop で Visual Studio Build Tools 2022 をインストール

# はじめに
`Atcoder`では、言語アップデート（2023年版）が予定されています。

https://atcoder.jp/posts/966

**乗るしかない、このビッグウェーブに**
# Crystal
TLEに悩むRubistの涙ぐましい努力もございますが、

https://qiita.com/superrino130/items/55d602f64360d55c51e8

Windows上で`Crystal`の実行及び確認ができると助かります。

https://crystal-lang.org/install/on_windows/
## Crystal の インストール
https://qiita.com/brp/items/5cd2a003b34971743afb

詳細は上記記事を参照していただきたいのですが、`VisualStudio`のインストールはどれをどうインストールするのか面倒。

ちなみに、`VisualStudio`のインストールなしで実行すると
```powershell
> crystal -v
Crystal 1.7.2 [29f9ac5] (2023-01-23)

LLVM: 13.0.1
Default target: x86_64-pc-windows-msvc

> crystal .\main.cr
Error: Could not execute linker: `cl.exe`: File not found
Run with `--verbose` to print the full linker command. 
```
`cl.exe`が無いって怒られます。
## cl.exe とは
https://learn.microsoft.com/ja-jp/cpp/build/reference/compiler-options?view=msvc-170

> cl.exe は、Microsoft C++ (MSVC) C および C++ コンパイラとリンカーを制御するツールです。
## Scoop で Visual Studio Build Tools 2022 のインストール
面倒に思う人が沢山いたのだと思われますが、`VisualStudioBuildTools`用のパッケージが用意されていました。
```powershell
scoop install vs_2022_cpp_build_tools
```

コマンドを実行すると、インストーラがダウンロードされてインストールが実行されます。
![20230206b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/5218b949-4b70-5562-5b74-c0a32fcfe381.png)

但し、インストール先は、scoopフォルダ内ではなく、`C:\Program Files (x86)\Microsoft Visual Studio`となりました。

```powershell
Checking hash of vs_BuildTools.exe ... ok.
Running installer... error.
ERROR Exit code was 3010!
Installation aborted. You might need to run 'scoop uninstall vs_2022_cpp_build_tools' before trying again.
```
エラー3010が発生しますが、再起動すれば大丈夫です。

https://github.com/neatorobito/scoop-crystal

> If you don't already have the correct Visual Studio components discussed earlier, run scoop install vs_2022_cpp_build_tools. The Visual Studio Installer UI will open to display progress. If you see ERROR Exit code was 3010!, this simply means you need to reboot. Run the same command again and reboot.
## Hello Crystal
```powershell
> crystal .\main.cr
ライブラリ crystal-run-main.tmp.lib とオブジェクト crystal-run-main.tmp.exp を作成中
Hello Crystal
```
# c/c++系 での利用
https://qiita.com/javacommons/items/37ec9429a60db20658e2

`cl.exe`があるということは、`C/C++`系の言語を使用できますので、競プロにとって有効と思われます。
# まとめ
+ scoop による Crystal の環境構築に成功した
neosでlogix その109

# 概要
neosでlogixやってみる。
logixを、俺コードで表現してみる。

# 参考にしたページ

https://qiita.com/t-yamanashi/items/aac637621dc86f9e3bdd

# 俺コード

```
a = Timer 1
{b, c} = ++ a
PlayOneShot c SinWaveClip
Int = b
d = % Int 2
SinWaveClip.Frequency = Multiplex 440 880 d

```

以上。
ESP32: GPIO 入力

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/d11f45ca-3794-ebb5-cd44-0821cf012415.png)

## プログラム

```text:button_monitor.ino
// ---------------------------------------------------------------------
//	button_monitor.ino
//
//						Feb/04/2023
// ---------------------------------------------------------------------
#define	PROGRAM	"button_monitor.ino"
#define	VERSION	"2023-2-4 AM 10:30"

const int buttonPin = 15;  // the number of the pushbutton pin
const int ledPin = 13;    // the number of the LED pin

// variables will change:
int buttonState = 0;
int buttonState_before = 0;

// ---------------------------------------------------------------------
void setup()
{
	Serial.begin(115200);
	delay(3000);
	Serial.println(PROGRAM);
	Serial.println(VERSION);
	Serial.println();

	pinMode(ledPin, OUTPUT);
	pinMode(buttonPin, INPUT);
}

// ---------------------------------------------------------------------
void loop() {
	buttonState = digitalRead(buttonPin);

	if (buttonState == HIGH) {
		digitalWrite(ledPin, HIGH);
	} else {
		digitalWrite(ledPin, LOW);
	}

	if (buttonState_before != buttonState)
		{
		Serial.println(buttonState);
		Serial.println(PROGRAM);
		Serial.println(VERSION);
		Serial.println();

		buttonState_before = buttonState;
		}
}

// ---------------------------------------------------------------------
```
Oracle Databaseのパスワードをハッシュ値で変更してみた

# はじめに

Oracle Databaseのパスワードは、パスワードベースのキー導出関数(PBKDF2)およびSHA-512暗号化ハッシュ関数を含む非最適化されたアルゴリズムに基づいてハッシュ化されています（[Oracle Databaseの組込みパスワード保護の概要](https://docs.oracle.com/cd/F19136_01/dbseg/configuring-authentication.html#GUID-F589A896-D775-4828-89F8-6A2BBEA413FE)）。
その保存されているハッシュ値ベースでもパスワードを設定できるため、その方法を紹介します。
たとえば、パスワードを変更前に戻してほしいが誰もパスワードはわからない、といったケースに利用できます（レアケースですが、、）。

# パスワードハッシュ値の確認
今回はOracle XE 21cの環境を利用します。
XEPDB1というPDBにTEST01というユーザを hogehogehoge というパスワードで作成し、接続してみます。

11g辺りまではdba_usersのPASSWORDでハッシュ値が確認できましたが、12c以降はできないです。
```SQL:ユーザ作成
SQL> create user test01 identified by hogehogehoge;

ユーザーが作成されました。

SQL> grant create session to test01;

権限付与が成功しました。

SQL> select username, password from dba_users where username like 'TEST%';

USERNAME                       PASSWORD
------------------------------ --------------------------------------------------------------
TEST01

SQL> conn test01/hogehogehoge@xepdb1;
接続されました。
```

sysdbaに戻り、ハッシュ値を確認します、一部マスクしてます。
```SQL:ハッシュ値の確認
SQL> SELECT name, spare4 FROM sys.user$ where name like 'TEST%';

NAME       SPARE4
---------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
TEST01     S:xxxxxxxxx2570779B32F28E134FA26A64B0EBB68B85904A9xxxxxxxxxxxx;T:xxxxxxxxxxxxxxx3F85932D369AF3113F26310E9BE2DDBE57090A22D0AF7D8355B18B8541D853D5AA87F7E9xxxxxx7B0DBEBF73572861C3F9B4473E43081C4EC099265261342B78AB6F7BCBF67Bxxxxx
```

# ハッシュ値でのパスワード変更
この状態で一度 TEST01 ユーザのパスワードを新パスワード asahidetest01 に変更します。
```SQL:TEST01ユーザの新パスワードへの変更
SQL> alter user test01 identified by asahidetest01;

ユーザーが変更されました。

SQL> conn test01/asahidetest01@xepdb1;
接続されました。
```
元のパスワード（hogehogehoge）では当然接続できません。
```SQL:元のパスワードでの接続失敗
SQL> conn test01/hogehogehoge@xepdb1;
ERROR:
ORA-01017: ユーザー名/パスワードが無効です。ログオンは拒否されました。

警告: Oracleにはもう接続されていません。
```

ハッシュ値の確認、で確認したパスワードへ戻し（一部マスク化してます）、元のパスワード(hogehogehoge)で再接続してみます。無事接続されました。
```SQL:ハッシュ値でのパスワード変更と元のパスワードでの再接続
SQL> alter user test01 identified by values 'S:xxxxxxxxx2570779B32F28E134FA26A64B0EBB68B85904A9xxxxxxxxxxxx;T:xxxxxxxxxxxxxxx3F85932D369AF3113F26310E9BE2DDBE57090A22D0AF7D8355B18B8541D853D5AA87F7E9xxxxxx7B0DBEBF73572861C3F9B4473E43081C4EC099265261342B78AB6F7BCBF67Bxxxxx';

ユーザーが変更されました。

SQL> conn test01/hogehogehoge@xepdb1;
接続されました。
```

# まとめ
ということで、定期的に sys.user$ の spare4 の値を取得しておくことで、パスワードがわからなくなってもリカバリは可能となります。
あまり使い道はないかもしれませんが、クライアント側でもパスワードを暗号化して保持されていることが増えてきてますので、緊急時には利用できるかもしれません。

# 参考

- [Oracle 12c IDENTIFIED BY VALUES](http://www.peasland.net/2016/02/18/oracle-12c-identified-by-values/)
Jupyterの可視化でよく使うdisplay()を水平(横)方向に出力する

## 0. はじめに
今回は軽い記事です。

Jupyterを使用してる時、データフレーム等をセルの出力結果に複数出力させる時によく使う`display()`
これは以下のように1個のセルで複数のデータフレームを「垂直」に出力できます。

```python: 垂直にdisplay
import IPython.display # これ不要だけど一応
import numpy as np

#サンプル用のデータフレーム
np.random.seed(7) # 乱数固定
sample_df = pd.DataFrame(np.random.uniform(size=(5, 2)))

display(sample_df.head())
display(sample_df.head())
```
![垂直.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373060/fc07bc09-0f33-ed95-d752-f80724fe858c.png)


これを水平にしたいと思ったことないですか？ 行数多いとスクロールしないと見えないですし、2つのデータフレームを行比較したいときにこの表示だと不便ですよね？
ということで今回は水平に表示させてみます。

## 1. displayで水平表示

初期機能ではないため、参考をほぼ流用しましたが作ってしましましょう。

ポイントは以下
・`_repr_html_()`でNotebookセルの最後のアイテムであるときに`to_html()`を呼び出している
・`<div style="float">{}</div>`でHTMLのdiv要素を横並びに配置
・paddingはdf間の幅なので、好きに設定すればいい

```python: 水平にdisplay
def show_many_heads(*dfs, n=5):
    class HorizontalDisplay:
        def _repr_html_(self):
            template = '<div style="float: left; padding: 5px;">{}</div>'
            return  ''.join(template.format(df.head(n)._repr_html_()) for df in dfs)
    return HorizontalDisplay()

# 2個のdfを垂直表示
show_many_heads(sample_df, sample_df, n=5)
```

![水平.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373060/3cb88839-5de6-bcae-4afb-d951573a5773.png)

水平方向にセル出力の表示サイズを超えた場合は下に続いて表示される
```python: 水平に無茶苦茶多くdisplay
#通常のdisplayと組み合わせてもOK
display(show_many_heads(sample_df, sample_df, n=2))
display(show_many_heads(sample_df, sample_df, sample_df, sample_df, sample_df, n=3))
```
![水平多数.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373060/2605fb55-7813-a1d6-d28a-95e919e43b79.png)

今回は以上！

## 参考

https://stackoverflow.com/questions/34398054/ipython-notebook-cell-multiple-outputs![uploading...0]()

https://ksomemo.github.io/contents/qiita/Notebook%E3%81%AB%E8%A4%87%E6%95%B0%E3%81%AEDataFrame%E3%82%92(%E6%B0%B4%E5%B9%B3%E3%81%AB)%E5%87%BA%E5%8A%9B%E3%81%99%E3%82%8B+display%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6.html
ESP32: Lチカ

Ubuntu 24.04 上の Arduino IDE 2.3.2 を使いました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/7292609c-e5cf-da19-41f2-26444561925c.png)


## プログラム

```text:led_flash.ino
// ---------------------------------------------------------------------
//	led_flash.ino
//
//						Feb/04/2023
// ---------------------------------------------------------------------
#define	PROGRAM	"led_flash.ino"
#define	VERSION	"2023-2-4 AM 10:30"

#define LED1 32
#define LED2 33
#define LED3 25
#define LED4 26
#define LED5 27
#define LED6 14
#define LED7 12
#define LED8 13

int leds[8] = {LED1,LED2,LED3,LED4,LED5,LED6,LED7,LED8};

// ---------------------------------------------------------------------
void setup()
{
	Serial.begin(115200);
	delay(3000);
	Serial.println(PROGRAM);
	Serial.println(VERSION);
	Serial.println();
	
	for (int it=0; it<8; it++)
		{
		pinMode(leds[it], OUTPUT);
		}
}

// ---------------------------------------------------------------------
void loop()
{
	for (int it=0; it<8; it++)
		{
  		digitalWrite(leds[it], HIGH);
		delay(1000);
		}

	for (int it=0; it<8; it++)
		{
  		digitalWrite(leds[it], LOW);
		}

	delay(1000);

	Serial.println(PROGRAM);
	Serial.println(VERSION);
	Serial.println();
}

// ---------------------------------------------------------------------
```
ggplotで凡例の形を色ごとに変えたい（R-wakalangへの質問と回答）



# Question

R-wakalangにこんな質問をした。

>ggplotを用いて、次のような図を描きました。
>penguinsの種族と性別ごとの違いに注目するために、
>species列とsex列を合わせたspecies_sex列を作り、
>bill_length_mmとbody_mass_gで散布図を作っています。
>区別のため、species_sex列で色分けし、sex列ごとに点のshapeを変えています。
>ここで、凡例のspecies_sexの説明で、sexごとにshapeを変える（Maleを▲、Femaleを●に合わせる）にす>るようなことはできるでしょうか。

``` Question.R
library(palmerpenguins)
library(tidyverse)

short_penguins <-  penguins %>%
  filter(!is.na(sex)) %>%
  sample_n(30,replace=FALSE) %>%
  transform(species_sex = paste(species,sex,sep="-"))
  
ggplot(short_penguins, aes(x=bill_length_mm,
                           y=body_mass_g,
                           color=species_sex,
                           shape=sex)) +
  geom_point() 
  

```

要するに、ここの形を変えたい。
![penguin_sex.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80212/8bee6c26-355d-665a-4957-2a3499a14341.png)


# Answer
>（ Thanks to tasasaki様）
>このあたりが参考になりそうです
>https://stackoverflow.com/questions/12410908/combine-legends-for-color-and-shape-into-a-single-legend

scale_color_manual、scale_shape_manualを使うといいようです。

``` Answer1.R
short_penguins <-  penguins %>%
  filter(!is.na(sex)) %>%
  sample_n(30,replace=FALSE) %>%
  transform(species_sex = paste(species,sex,sep="-"))
  
ggplot(short_penguins, aes(x=bill_length_mm,
                           y=body_mass_g,
                           color=species_sex,
                           shape=species_sex)) + #colorとsphapeでおなじものを指定
  geom_point() +
  scale_color_manual(values=c("red","red","blue","blue","green","green")) +
  scale_shape_manual(values=c("circle","triangle","circle","triangle","circle","triangle"))

```
![Qiita-penguins2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80212/26aadea0-f573-3d48-82e3-88da51c76375.png)


色を変える必要がない場合には、scale_shape_manualだけでも大丈夫

``` Anser2.R
short_penguins <-  penguins %>%
  filter(!is.na(sex)) %>%
  sample_n(30,replace=FALSE) %>%
  transform(species_sex = paste(species,sex,sep="-"))
  
ggplot(short_penguins, aes(x=bill_length_mm,
                           y=body_mass_g,
                           color=species_sex,
                           shape=species_sex)) + #colorとsphapeでおなじものを指定
  geom_point() +
 scale_shape_manual(values=c("circle","triangle","circle","triangle","circle","triangle")) +
  labs(color = "Species and sex", shape = "Species and sex") #ラベルを変えるときは、ShapeとColorを同じ名前にする

```
![Qiita-penguins3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80212/88baa667-9bdd-f0e3-6832-90b4fb9bc6cc.png)

# さいごに
ｒ−wakalangのr-beginnersチャンネルでは、R初心者のちょっとした疑問を、Rつよつよなお兄さん、お姉さんたちが爆速で解説してくれます。（いつも大変お世話になっております）
みなさんとってもフレンドリーなので、みんなで楽しくRを勉強しましょう！
（腕に覚えのある皆様はご回答のほうも何卒）

# 参考:
- [Stack over flow: Combine legends for color and shape into a single legend](https://stackoverflow.com/questions/12410908/combine-legends-for-color-and-shape-into-a-single-legend) 

- [ggplotで使われるShapeなど](https://ggplot2.tidyverse.org/articles/ggplot2-specs.html)

- [r-wakalangの紹介](https://qiita.com/uri/items/5583e91bb5301ed5a4ba)
dart(flutter)でのlistの比較方法

## 実装

```dart
import 'package:collection/collection.dart';

var list1 = <int>[1,2,3];
var list2 = <int>[1,2,3];

print(list1.equals(list2));
// true
```

## 参照
https://rrtutors.com/tutorials/How-can-I-compare-List-and-Maps-in-Flutter
Azure と GitHub Actions の連携を CLI だけで試してみた

Azure と GitHub Actions の連携を CLI だけで試してみました。

## 自分の検証環境


```bash
$ az version
{
  "azure-cli": "2.43.0",
  "azure-cli-core": "2.43.0",
  "azure-cli-telemetry": "1.0.8",
  "extensions": {}
}

$ gh --version
gh version 2.20.2 (2022-11-15)
https://github.com/cli/cli/releases/tag/v2.20.2
```

## Azure CLI と GitHub CLI だけで検証


```bash
prefix=mnrgapp
region=japaneast

gid=$(az group create \
  --name ${prefix}-rg \
  --location $region \
  --query id \
  --output tsv)

auth=$(az ad sp create-for-rbac \
  --name ${prefix} \
  --years 100 \
  --role Contributor \
  --sdk-auth true \
  --scopes $gid)

gh repo create ${prefix} \
  --private

gh secret set AZURE_CREDENTIALS \
  --repo mnrst/${prefix} \
  --body "$auth"

mkdir ${prefix}

cd ${prefix}

mkdir -p .github/workflows

cat <<"EOF" > .github/workflows/azure-login-test.yml
on: [push]

name: AzureLoginSample

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Login with Azure
        uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}
      - name: Azure CLI script
        uses: azure/CLI@v1
        with:
          azcliversion: 2.43.0
          inlineScript: |
            az group list -o table
EOF

git init

git add -A

git commit -m "first commit"

git branch -m main

git remote add origin https://github.com/mnrst/${prefix}.git

git push -u origin main
```

## 検証結果

GitHub Actions から Azure サービスプリンシパルで許可したリソースグループだけがリストに表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/894c8b80-cbc3-4a00-adfd-9b8fdcb92253.png)

## 参考

https://learn.microsoft.com/ja-jp/azure/developer/github/connect-from-azure?tabs=azure-cli%2Clinux

https://cli.github.com/manual/
VSCodeのCSS Peekがpugファイルに対応しない

## pugも対応フォーマットに含まれているのに？？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520632/c1b2b49c-afc8-dfaa-3869-c1fd9613bf27.png)

とあるブログでpugも対応している。と記載しているところもありました・・・。

## 結論：CSS Peekはpug未対応です！
公式の説明ページではHTMLとejsコード編集についてしか記述がない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520632/ae0e7e74-0771-8aa0-566a-b167296ca7ae.png)

GitHubのissuesにpugはサポートしてないと返答している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520632/e688a04e-7e9d-4f57-e865-21436de22148.png)

プラグインの設定にpugって書いてあるから対応していると思いきや、まだ対応してないみたいです。ややこしいですね^^;
pug編集中にCSSの定義元追えたら、かなりコーディングが捗ったので未対応ということで残念でした。
他にもpugに対応しているツールはないか探したんですが、ないみたいです。大人しく手動でCSS見に行きましょう・・・
matting用のtrimapをマスク画像から作る方法

# Mattingはセグメンテーションの境界をくっきりさせる


# Mattingには、trimap画像が必要
セグメンテーション・マスクの境界をよりくっきり強化するmattingには、trimap画像が必要です。
trimapは、マスクの境界の、オブジェクトか背景か曖昧な部分がグレーになっている画像です。
しかし、人力でtrimapを作るのは時間と手間がかかります。

# マスク画像から自動でtrimapを作る方法

U2netなどでマスク画像を作り、以下の関数でtrimapを作成します。

```python
import numpy as np
from scipy.ndimage import binary_erosion
import cv2

def make_trimap(mask,foreground_threshold=240,background_threshold=10,erode_structure_size=10): 
    # erode_structure_size で曖昧な領域の侵食度合いを決定します。
    is_foreground = mask > foreground_threshold
    is_background = mask < background_threshold
    
    structure = None
    if erode_structure_size > 0:
        structure = np.ones(
            (erode_structure_size, erode_structure_size), dtype=np.uint8
        )
    
    is_foreground = binary_erosion(is_foreground, structure=structure)
    is_background = binary_erosion(is_background, structure=structure, border_value=1)
    
    trimap = np.full(mask.shape, dtype=np.uint8, fill_value=128)
    trimap[is_foreground] = 255
    trimap[is_background] = 0
    return trimap
```

```python
mask = cv2.imread("mask.jpg")
mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY) # if your mask image has 3 channel.
trimap = make_trimap(mask)
```

画像
![pexels-pixabay-45201](https://user-images.githubusercontent.com/23278992/216488775-d90ede51-218a-427e-950e-2c55f3e65879.jpg)

マスク
![result (63)](https://user-images.githubusercontent.com/23278992/216488782-609aa7bb-2fa5-4fa7-8219-ee0e8345e449.png)

トライマップ
![trimap](https://user-images.githubusercontent.com/23278992/216488796-231b52b4-202b-408a-a35f-62901657c0ae.png)
pythonスクリプトにargをつける方法

# Pythonファイルのshell実行に引数をつけるやつ

### 記述

```python:arg_demo.py
import argparse

def parse_args():
    parser = argparse.ArgumentParser(description='demo')
    parser.add_argument('--input_path', type=str, help='input image file path')
    args = parser.parse_args()
    return args

def run()
    args = parse_args()
    print(args.input_path)

if __name__=='__main__':
    run()
```

### 呼び出し

```shell
python arg_demo.py --input_path image.jpg
```

>image.jpg
Swift（iOS）でお絵描きViewを追加する

# ユーザーに指で描画してもらいたい

![Feb-04-2023 07-29-38.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/3bce0994-373c-de56-41e2-f54e0e8b9b26.gif)
iPhoneをタッチして絵を描いてもらいたい場合、どのようにお絵描きできるViewを追加すればいいのでしょうか？

# ライブラリを追加すればOK

https://github.com/Asana/Drawsana

お絵描きライブラリはいろいろありますが、今回はこれで。

### インストール
Swift Package Manager、Carthage、ファイルのドラッグ&ドロップ、の方法がありますが、僕のお気に入りはSwift Package Managerです。

### 使う

### とりあえず描く

```swift
import UIKit
import Drawsana

let drawingView = DrawsanaView()
let penTool = PenTool()
let imageView = UIImageView()

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        drawingView.set(tool: penTool)
        drawingView.userSettings.strokeWidth = 10
        drawingView.userSettings.strokeColor = .black
        drawingView.userSettings.fillColor = .yellow
        drawingView.userSettings.fontSize = 24
        drawingView.userSettings.fontName = "Marker Felt"
        drawingView.frame = view.bounds
        view.addSubview(drawingView)
    }
}
```

これで描画ができる。

### 機能

消す

```swift
drawingView.operationStack.undo() // undo
drawingView.operationStack.redo() // redo
drawingView.set(tool: EraserTool()) // 消しゴムにする
```

保存

```swift

// フォトライブラリに保存
func saveFinalImage() {
    let image:UIImage? = drawingView.render()
    imageView.image = image
    UIImageWriteToSavedPhotosAlbum(image!, self, nil, nil)
}

// UIImageにオーバーラップさせる。drawingViewと同じサイズのUIImageViewを後ろに置いて描画すれば、ちょうどサイズを合わせてオーバーラップしてくれる。
func saveImageOnImage(_ backgroundUIImage:UIImage) {
    let overlapImage:UIImage? = drawingView.render(over:backgroundUIImage)
    imageView.image = overlapImage)
    UIImageWriteToSavedPhotosAlbum(overlapImage!, self, nil, nil)
}


// 以下はDrawingオブジェクトとして扱う場合。

func save() {
  let jsonEncoder = JSONEncoder()
  jsonEncoder.outputFormatting = [.prettyPrinted, .sortedKeys]
  let jsonData = try! jsonEncoder.encode(drawingView.drawing)
  // store jsonData somewhere
}

func load() {
  let data = Data()// load data from somewhere
  let jsonDecoder = JSONDecoder()
  let drawing = try! jsonDecoder.decode(Drawing.self, from: data)
  drawingView.drawing = drawing
}


```

いろいろな機能を試してみたければ、リポジトリのデモフォルダからViewControllerとColorPickerViewControllerとToolPickerViewControllerをコピーするのがおすすめ。

全ての機能はドキュメントで。

https://asana.github.io/Drawsana/index.html

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

機械学習、ARアプリ（Web/iOS）を作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)
React.Memoizationとは - useCallBackを使ってリレンダリングを防ぐ

直前の記事に続いて、子供コンポーネントに関数propsを追加して渡せば、どのような状況になるでしょ

```react:Comments.jsx
import React, { useCallback } from 'react'
import CommentItem from './CommentItem'

export default function Comments({commentList}) {
  // onClickイベントハンドラー関数
  const handleChange1 = (() => {
       console.log("push");
  });
  return (
    <div>
        {commentList.map(comment => <CommentItem 
            key={comment.id}
            title={comment.title}
            content={comment.content}
            likes={comment.likes}
            onClick={handleChange}
            />
        )}
    </div>
  )
}
```
Comments.jsxのCommentItem propsに固定のonClickを設けて、
```react:CommentItem.jsx
import React, { Profiler, memo } from 'react'
import './CommentItem.css'

function CommentItem({title, content, likes, onClick}) {
    function onRenderCallback(
        id,
        phase,
        actualDuration, 
        baseDuration,
        startTime,
        commitTime,
        interactions 
      ) {
        // レンダリング度にログを出力する！
        console.log(`actualDuration(${title}: ${actualDuration})`);
      }
    const handleClick = () => {
        onClick();
    }
   return (
      <Profiler id="CommentItem" onRender={onRenderCallback}>
        <div className="CommentItem" onClick={handleClick}>
            <span>{title}</span>
            <br />
            <span>{content}</span>
            <br />
            <span>{likes}</span>
        </div>
    </Profiler>
  )
}
export default memo(CommentItem); // memoはHOC!
```
CommentItemのeventHandlerに追加して、memoizationが効くのかを検証！

結果は以下。
結果からわかるように、前回のレンダ結果を再使用せず、また最初からレンダリングした結果を出しています。
![스크린샷 2023-02-04 09.34.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3097775/bdece06d-fcba-ad5c-5ad7-b72dc982d61d.png)

その理由としては、Memoizationの時にreactはpropsを比較して再使用するかを決めています。
上記では、Commentsに関数のpropsを新しく追加したので、reactは前Propsと現Propsを比較し、違うものと判断して
再レンダリングしちゃいます。
（shallow compare : 基本タイプデータの場合、値が同一かどうかだけを比較。
オブジェクトの場合は、参照だけを比較する。値が同じでも、参照値が異なるため、再レンドリンが発生する。）

この場合に使用できるのが{ useCallback } HOOKです。
useCallbackは関数（Object）をmemoizationしてくれます。
<b>useCallbackは、関数を保存するhookです。reactに関数を保存し、実行ごとに再生成しないようにします。</b>
メモリ内の同一の場所のいずれかに保存されるため、同一の関数（オブジェクト）であるか比較することができます！

```react:Comments.jsx:useCallback適用
  import React, { useCallback } from 'react'
  //　（・・・省略）

  //修正前
  const handleChange1 = (() => {
       console.log("push");
  });
  //修正後
  const handleChange = useCallback(() => {
      console.log("push");
  }, []);

```

10個のコンポーネントが作成された時点のログです。
useCallbackを使う前とは違く、ちゃんと前回の結果が再使用されていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3097775/a24e23a6-0802-d285-c655-62973e694856.png)
No.3 （ちょっと一息）ChatGPTにサンプルデータを作らせてみた

## はじめに
※本記事の内容は個人の検証をまとめたものであり、会社としての見解や推奨ではありません

いま流行りのChatGPTでデータ分析に活用できるサンプルデータが作れるという話を小耳に挟んだため、検証をしてみました。
ChatGPTの使い方を説明している記事ではなく、こんな事ができるんだなという事を見ていただければと思います。

### まずはシンプルに聞いてみる
・Power BIのサンプルCSV下さい！
![スクリーンショット 2023-02-04 9.07.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2943951/d5aa264a-c7b1-5052-21ef-177068beaa9e.png)
サンプルCSVがGetできるサイトを教えてもらいました。
アクセス先のサイトに行くと、サンプルcsvがあったので確かにこれも使えそうですが、折角なので追加で色々聞いてみました。

### CSVの作成を依頼してみる
・Power BIのサンプルCSVを**作って下さい！**
![スクリーンショット 2023-02-04 7.33.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2943951/fb1171fa-5bb6-96d0-d13f-47e1873734c4.png)

特に何も指定せず（丸投げ）で依頼してみましたが、、
勝手にいい感じのデータ、作ってくれましたね。驚きです。

もう少し分析に使えそうなデータが出せそうか、ねだってみましょう笑

### CSVの作成を具体的に依頼してみる①
・Power BIのサンプルCSVを**作って下さい！列は具体的にこれが必要です！**
![スクリーンショット 2023-02-04 7.35.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2943951/ae10a023-0f63-88c3-d3eb-f42b0562fe1e.png)

列に必要なデータを指定したらば、それに応じて用意してくれました。しかも、
「ID」→数値
「売上」→数値（通貨）
「成約フラグ」→Boolean
として**必要なデータ型に合わせて作成してくれています。** すごい。。

### CSVの作成を具体的に依頼してみる②
・Power BIのサンプルCSVを**作って下さい！列は具体的にこれが必要です！行も多めに下さい！あと色々指定します！**
![スクリーンショット 2023-02-04 9.33.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2943951/a69fec2f-3e92-9e0e-cdde-d7b85d171129.png)

行も5行以上出してくれました。解像度の高いデータになってきたと思うので、これからこのサンプルデータを使ってレポートを作成してみます。

### サンプルデータを元にレポートを作成する
**1．コードをコピーする（赤枠部分をクリック）**
![スクリーンショット 2023-02-04 9.38.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2943951/5d67a84f-7a3a-0750-d19b-5a80bac0c4f7.png)
**2.Excelにペーストしてカンマを元にデータを区切る**
![スクリーンショット 2023-02-04 9.39.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2943951/b4a1da71-ca2c-12bb-268d-db4e970e4234.png)
**3.Power BIサービスにExcelのデータを貼り付ける（データ型も併せて指定する）**
![スクリーンショット 2023-02-04 9.40.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2943951/0bcc2293-c9db-40b0-a666-5d0b71eb7fa0.png)
※データのインポートの方法は下記セッションで解説していますので、参考にしてください。
リンク：[No.1 データのインポート方法](https://qiita.com/shinyasasaki/items/c9559fa9dec34fdcd9a8#3%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E8%B2%BC%E3%82%8A%E4%BB%98%E3%81%91)

**4.レポートを自動作成する**
![スクリーンショット 2023-02-04 9.41.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2943951/bffe0dd0-639b-50da-3186-24d58f5c6ace.png)
・・・できましたね。

今までサンプルのデータを作るのにアレコレ考えながら作っていたのですが、もしかするとそういった苦悩（？）などはこれから不要になるかもしれません。。
本練習帳においては[サンプルデータリンク（ダウンロード可）](https://livesend.microsoft.com/i/ehl3PLUSSIGNJTX8BIRHzoW3ybEhoYraZNZoPWKBFOknwGBZULuBStvXgn1YOyabPLUSSIGNCeKNHU6EHRDPLUSSIGNOyNRPR2pU61FPLUSSIGNqzP07kWqtTSFOPLUSSIGN69F8dlYf5SiFhVK0gizhUXGoEWJypod)を用意していますが、他にも色々触ってみたいという方はChatGPTを使ってみるのも良いかもしれないですね。


こちらのセッションは以上です。
[→ Power BI サービス練習帳に戻る](https://qiita.com/shinyasasaki/items/391d50c2508794e8fcfd)
【Swift】基本文法メモ

Swiftの基礎的な文法を備忘録としてまとめてみました。

[1. 標準入力からの値取得方法](#1-標準入力からの値取得方法) 
[2. varとletの違い](#2-varとletの違い)
[3. 文字列分割](#3-文字列分割) 
[4. 型変換と加減剰余](#4-型変換と加減剰余) 
[5. コレクション](#5-コレクション)
[6. 繰り返し処理](#6-繰り返し処理)
[7. 改行なしで出力](#7-改行なしで出力)
[8. 小数点の扱い方](#8-小数点の扱い方)
[9. 条件分岐と論理演算](#9-条件分岐と論理演算)

### 1. 標準入力からの値取得方法
```swift
let inputLine = readLine()!
let inputDouble = Double(readLine()!)!
let inputInt = Int(readLine()!)!
```

### 2. varとletの違い

```swift
let constant = "定数"
// constant = "値を書き換えられない"
var variable = "変数"
variable = "値を書き換えられる"
```

### 3. 文字列分割
```swift
import Foundation
let strNums = "5 2.5"
//スペースで区切る
let arr:[String] = strNums.components(separatedBy: " ")
print(arr[0]) // 5
print(arr[1]) // 2.5
//文字列連結となる
print(arr[0] + arr[1]) // 52.5
```

### 4. 型変換と加減剰余
```swift
let strNum1 = "5"
let strNum2 = "2.5"
// String → Double
let doubleNum1:Double = Double(strNum1)!
let doubleNum2:Double = Double(strNum2)!
print(doubleNum1) // 5.0
print(doubleNum2) // 2.5
print(doubleNum1 + doubleNum2) // 7.5

let strNum3 = "30"
// String → Int
let num3 = Int(strNum3)!
print(num3 + 5) //35
print(num3 - 5) //25
print(num3 * 5) //150
print(num3 / 5) //6
print(num3 % 5) //0
// Int → String
print(String(num3) + strNum2) //302.5(文字列連結)
```

### 5. コレクション
```swift
//配列
var arr: [Double] = [2.1, 4.2, 6.3, 8.4, 10.5]
print(arr[3]) //8.4
print(arr.count) //5(配列の要素数)

//集合
var num: Set<Int> = [1, 2, 3]
print(num.first!) // 1 or 2 or 3

//辞書
let dict: [Int: String] = [1:"りんご",2:"みかん", 3:"バナナ"]
for (key , value) in dict {
  print("\(key): \(value)")
}
//　順不同
// 3: バナナ
// 1: りんご
// 2: みかん
```

### 6. 繰り返し処理
```swift
// 開始位置と終了位置指定
var total = 0
for i in 1...10 {
    total += i
}
print(total) //55

// 配列指定
var arr: [Double] = [3.1, 1.3, 5.7]
var total:Double = 0

for num in arr {	 	 
  total += num	 	 
}
print(total) //10.100000000000001
```

### 7. 改行なしで出力

```swift
var arr: [Double] = [3.1, 1.3, 5.7]
for num in arr {	 	 
  print(num, terminator: ",") //3.1,1.3,5.7,	 	 
}
print()
for num in arr {	 	 
  print(num, terminator: "") //3.11.35.7	 	 
}

```


### 8. 小数点の扱い方
```swift
var num:Double = 10.100000000000001
//切り捨て
print(floor(num)) // 10.0
//切り上げ
print(ceil(num)) // 11.0
//四捨五入
print(round(num)) // 10.0

// 小数点の位置をずらしたい場合
num = num * 10
//切り捨て
print(floor(num) / 10) // 10.1
//切り上げ
print(ceil(num) / 10) // 10.2
//四捨五入
print(round(num) / 10) // 10.1

```

### 9. 条件分岐と論理演算
```swift
let boo = true && false //false(論理積)

if (boo == false) {
    print("偽です")
} else {
    print("真です")
}
// 偽です

```
ボクのカイハツニッキ【Rails】

# Overview
- 今週から、毎週土日のどっちかにレポートを書いてみることにしました。
- 日々の気づきや発見を定期的に文章化することで頭の中を整理するためです。
- 基本は具体的なテクニックではなく抽象的な「考え方」とか「発見」を書いていく予定ですが、最低１つコードも載せられたらいいですね。
  - いくつも記事を分割してもいいけども、後々消すかもしれないので１つの記事に追加していく感じで縦に長いレポートにできればと思います。



# 2023.02.04
### Titlte
- テストでプログラミングが10倍楽しくなる！

### Overview
- 久々にがっつりウェブアプリ開発した週でした。
- test code, product codeを順番にリズムよく描きながら開発するのは爽快ですね！
  - testが動けば自分の設計力の高さに陶酔でき、testが動かなければ１つ学べる。
  - 動いても動かなくても面白いなんて最高じゃないですか。
  - テストを書いていないときは小さなバグがどこに影響しているか不安になりながらコード書いてた気がします。
- ただその中でも良かった点と改善点が出てきたので以下で紹介しようかなって思います。

### TDD良かった点
- procuct codeを書く前に即時的な設計ができるので、全体像を把握しながらコーディングできる安心感。
- １つ機能を実装するごとに全てがGreenになることによるこれまた安心感。
- 思い通りに動かない時に自分のロジカルの低さを痛感することで学びになる。

### TDDやる上での改善点
- railsやrubyに依存したコードをあまり書かずに、極論`assert_rqual`だけでテストをかければそれが一番汎用的だと思う。
- fixtureの中がごちゃごちゃになってレコードの数を数えるときに定数ではなく`Model.where(x: y).count`のようなことをやってしまう。

### 今週面白いなと思った気づき
- テストファイルの中を無理やりクラスで分割してみやすくしてみた。
- これまでは１つのテストファイルの中に`test 'x' do`が並列であったから可読性が低かった。
- これだとテストの種類ごとにグループ分けできるのでみやすいかなと思ってやってます。
  - ただ、グループごとにテストを実行できればいいなと思います。
  - ex. 例えばAccessCheckクラスの中身だけを実行したいとかできればいいな。

```ruby
class SetUp < self
  def setup
    @one = 1
  end
end
class AccessCheck < SetUp
  class ValidCase < self
    test '' do
      assert_equal 1, @one
    end
  end
  class InvalidCase < self
  end
end
class Default < SetUp
  class ValidCase < self
  end
  class InvalidCase < self
  end
end
``
スケジュールトリガーフローを使ってみた

## スケジュールトリガーフローとは
スケジュールトリガーフローはフローの一種でノーコードで定期的な自動化処理を出来るものです。
簡易なバッチ処理であればApexで書くよりも楽に処理できる可能性があります。
ただし後述しますがデバッグログで表示できる情報が少なく制約もありますのでそこに留意する必要があります。

## 例１.取引先のバッチ処理
たとえば請求先住所を納入先住所をコピーするバッチ処理は以下のようになるかと思います
![flow2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510376/28fdb744-e36f-a4b3-abba-fe1c95b4bb9d.png)


オブジェクトおよび検索条件は以下の通りです。
今回は簡易的に都道府県（請求先）に値があり都道府県（納入先）に値がないとしました。
![search.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510376/6dfa4f33-7597-78d8-e93b-8a9f26bf9233.png)

更に条件分岐として検索条件で取得できたオブジェクトの都道府県（請求先）が
東京都かそれ以外かで処理を分岐しています。
![Decision.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510376/3350fc08-4ef4-ddd1-a756-8d6639250d6e.png)



分岐先で東京都更新、東京都以外更新で分かれていますが、説明項目以外は同様の処理をしており請求先の値を納入先へコピーしています。
![updateTokyo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510376/795ee78f-f3c9-4086-ec73-b47633dd8f7e.png)


:::note info
レコードのバッチに対して実行されるフローのスケジュールトリガ
https://help.salesforce.com/s/articleView?id=sf.flow_concepts_trigger_schedule.htm&type=5
スケジュール済みフローを作成するときに、レコードの項目値にアクセスするには $Record グローバル変数を参照します。
:::

## デバッグ時の考慮点
完成したタイミングでデバッグをすることができますが、いくつか考慮すべきところがあります。
**１．2以上の条件に合致する場合でも、サンプルとして一つしか処理しない**
**２．こちら側で任意のレコードを選択することが出来ず、システム側で条件に合致したレコードを自動的に選択する。**

したがってデバッグで詳細を確認したい場合、今回のように条件で結果が異なる時は
初めに合致したレコードIdをデバッグから取得し別条件を別途設定し直す必要が出てきます。


**３．この時点で何件スケジュールトリガーフローに処理されるかわからない**
検索条件に合致するレコードはヘルプに記載がある通り、25万件か200×ユーザ数の多いほうまでは処理が可能ですがデバッグ上には何件条件に合致して処理されるのか情報が出てきません。
これは実際にスケジュールトリガーフローを動かしてみるまでよくわかりません。

:::note info
スケジュールトリガフローに関する考慮事項
https://help.salesforce.com/s/articleView?id=sf.flow_considerations_trigger_schedule.htm&type=5
・24 時間あたりのスケジュールトリガフローインタビューの最大数は、250,000 または組織のユーザライセンス数の 200 倍の大きい方です
・自動化プロセスユーザがスケジュールトリガフローを実行します。
:::

また実際に動かして、開発者コンソールからログから詳細を取得するには以下の準備が必要です。
デバッグログのユーザ追跡フラグを新規作成し追跡対象エンティティ種別を自動化プロセスに設定し、デバッグレベルでワークフローをより詳細に設定した上で有効期限内にスケジュールトリガーフローを動かす必要があります。

上記のデバッグログを仕込み、開発者コンソールを開いたうえで、Show my Corrent Logにチェックを外せば以下のように確認が出来るはずです
![log3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510376/54f26006-a72d-6027-b64c-aff5e0e89338.png)

図にある通り、1万件を超えるレコードでも問題なく実行できていることが確認できます。
ただし、このデバッグログでは具体的な処理が残らないので、処理を確認する必要があるときはフロー上のデバッグで確認する必要が出てきます。

## 例２．$Recordなしで同じ処理をした場合は
基本的にはレコードトリガーフローはオブジェクトと検索条件をはじめに設定した上で
$Record（検索条件に該当するレコード）を使用して値の更新をするほうが1万件を超えるような多数のレコードを処理できます。
しかし$Record以外のレコードをスケジュールトリガーフローで処理したいときもあるかもしれません。

スケジュールトリガーフロー上で$Record以外も処理は可能ですし細かく作りこむこともできますが、どこまで処理ができるのでしょうか。

ここでは例１で処理した同じ内容を$Recordを使わず処理をしようとした場合はどのような結果になるか試してみます。

例１を$Recordを使わずに処理しようとする場合は以下のような形になります。
処理は一緒ですので説明は割愛させていただきます。

![flow3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510376/3389e890-6872-8f8a-006d-e41e5492a3fe.png)


これをフロー上のデバッグを押してみると10分以上かかった挙句に以下のように処理が失敗してしまいます。

![errorflow2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510376/d0b41efa-afe9-18b2-4d5f-526dc5c05029.png)


エラーメッセージは「Apex CPU time limit exceeded」でこれはSalesforce固有の制限によるエラー（ガバナ制限）です。
エラー直前のログをみると1768件目のレコードの処理中に制限に引っかかったようです。


このように$Record以外を使用してスケジュールトリガーフローを使用する場合は十分処理件数に気を付けたうえでフローを作成する必要があります。
【TypeScript】Mockdate使って現在日時を固定化

## 背景
ladle(storybookのようなコンポーネントカタログ)にて、日時表示のバリエーションを持たせたかった。そのためには、現在日時をmock(固定化)する必要があった。

## 導入

```terminal
$ npm install mockdate --save-dev
```
https://www.npmjs.com/package/mockdate

## 使い方
importして、

```typescript
import MockDate from 'mockdate'
```
このようにセットするだけ
```typescript
MockDate.set(2011, 2, 11, 14, 46, 0, 0, 0)
console.log(new Date());
```
無事に現在時刻をmockできました！
![スクリーンショット 2023-02-04 8.52.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693502/77094edf-4857-76c3-493e-1a95eae1485e.png)
テスト86

```vb
Sub Error_test()

'「On Error GoTo Err_Exit」を通すか通さないかによって、
'エラーがあった時に、以下のように処理を分けられる
'1，止めずに後処理をする
'2，止めてどこでエラーがあったかわかるようにする

'この処理を作った理由は、1のように通常通りエラー処理をすると
'エラーメッセージは出せるけどエラー処理で終了してしまい、具体的に
'どのコードでエラーがあったかわからなくなってしまうため。

'そのため2をできるようにしたのが以下のコード

With ThisWorkbook.Sheets("テスト2")

    If .Range("A1").Value = 1 Then
    
        On Error GoTo Err_Exit
    
    End If

End With

'A1セルを空欄にした場合、以下のコードで止まる
Err.Raise 11111

Exit Sub

Err_Exit:
'A1セルを1にした場合、以下のコードでエラーメッセージを出して終了
MsgBox Err.Number & vbCrLf & Err.Description


End Sub
neosでlogix その107

# 概要
neosでlogixやってみる。
logixを、俺コードで表現してみる。

# 参考にしたページ

https://qiita.com/ohisama@github/items/3a52d33459863bd21d63

# 写真

![2023-02-03 21.49.04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/dc486437-f97b-beee-2684-42bc965e48f4.jpeg)


# 俺コード
アンカーに入ってBackSpaceキーでジャンプする箱
```
{a, b} = KeyHeld BackSpace
	|> FireOnTrue
	|> WriteRef LocalUser
SetCharactorVelocity b 0,5,0 CharacterController
CharacterController.SimulatingUser = a


```

以上。
Azure VM 上のスクリプトファイルを Rest API で実行する

Azure Rest API で、Azure Virtual Machine 上の C:\test.ps1 というスクリプトファイルを実行するためのメモ。

## API

- Virtual Machines - Run Command
https://learn.microsoft.com/ja-jp/rest/api/compute/virtual-machines/run-command?tabs=HTTP 

[URI] で対象の VM を指定する。

POST https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}/runCommand?api-version=2022-08-01

[本文] で実行するコマンドや .ps1 ファイルを指定する。ここでは test.ps1。

```powershell
{
  "commandId": "RunPowerShellScript",
  "script": [
    "powershell C:\\test.ps1"
  ]
}
```

Logic Apps でやろうとすると以下。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/cb26210f-5523-f31c-7b54-4466f1cb0a98.png)

## 認証

- マネージド ID が簡単。
ここでは、VM 側の権限を Logic Apps に付与する。
まず Logic Apps 側にロールの割り当てができるように設定する。

[設定 - ID]、[システム割り当て済み] タブにて [状態] を “オン” にして保存。


### マネージド ID の有効化

- Azure Logic Apps でマネージド ID を使用して Azure リソースへのアクセスを認証する # Azure portal でシステム割り当て ID を有効にする
https://learn.microsoft.com/ja-jp/azure/logic-apps/create-managed-service-identity?tabs=consumption#enable-system-assigned-identity-in-azure-portal

- VMの権限を Logic Apps に付与する
[Virtual Machines] - [<対象の Virtual Machines >] - [アクセス制御 (IAM)] 
[+ 追加] から [ロールの割り当ての追加]。

[ロール] について、ここでは [仮想マシン共同作成者] ロールを使う。

- Virtual Machine Contributor
https://docs.microsoft.com/ja-jp/azure/role-based-access-control/built-in-roles#virtual-machine-contributor 
- コマンド実行には [Microsoft.Compute/virtualMachines/runCommand/action] 権限が必要

- Azure portal を使用して Azure ロールを割り当てる
https://learn.microsoft.com/ja-jp/azure/role-based-access-control/role-assignments-portal


## 仕上がり
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/1e3918b2-974e-cca7-0cbc-51c2668bddae.png)

以上です～
配列の正規化でArray()を使うな！

2023年2月某日、Twitterが氷河期になりTLが荒れ狂う最中、私は一つのコードに苛まされていた。
配列の正規化を行うため、以下のコードを実行したところ、

```rb
fp = File.new("hoge.mp4")
Array(fp)

=> ["謎のデータ配列"] # [fp] が帰ってくる予定だった
```

**は？？？？？？？？**

## 配列の正規化とは

配列またはObject、いずれかの値がやってくる場合に、
配列または[ Object ]、に変換しその後の処理を簡潔にするためのテクニックのこと

たとえば

```rb
def hoge(file_or_files)
  # ↓ ここが配列の正規化
  files = file_or_files.is_a?(Array) ? file_or_files : [file_or_files]
  
  files.each do |file|
    # 個々のファイルに対して処理をする
    ...
  end
end
```

のように書くと、引数の形式をそこまで気にせずに良くなるってヤツ


自分が確認した中では2種類の記法がある


### 方法1. 与えられた値を配列で囲んで、その後flattenする方法

書き方：
`[item_or_items].flatten`

```rb
# 配列を入れた場合
items = [:hoge]
[items].flatten
=> [:hoge]

# オブジェクトを入れた場合
items = :hoge
[items].flatten
=> [:hoge]
```

見たらわかると思うが、ぱっと見で何やってるのかわかりにくい
また当たり前だが、多重配列を使っている場合に、flattenしすぎる場合がある

```rb
items = [[:hoge]] # 二重配列
[items].flatten
=> [:hoge] # 一重配列
```


### 方法2. Array() って関数を使う方法

書き方：
`Array(item_or_items)`

```rb
# 配列を入れた場合
items = [:hoge]
Array(items)
=> [:hoge]

# オブジェクトを入れた場合
items = :hoge
Array(items)
=> [:hoge]
```


自分は最初、方法1.の方を使用していたものの

- 方法2. の方がぱっと見で何してるかわかりやすい
- 方法2. では多重配列の次元数が下がりすぎることがない

という理由から、もっぱら最近は 方法2. を利用するようになっていた

## 今回何が起きたのか

さて、今回起きたことに戻ろう

```rb
fp = File.new("hoge.mp4")
Array(fp)

=> ["謎のデータ配列"] # [fp] が帰ってくる予定だった
```

返り値を見てる限り、なんとなくファイルのデータがそのまま出てきてる感じがする
じゃあなんでそんなことが起きるのか。色々試してたらなんか見つけた

```rb
fp = File.new("hoge.mp4")
fp.to_a

=> ["謎のデータ配列"] # Array(fp) の時と同じ値
```

**ぉん？**

なるほど、もしかしたら `Array(obj)` って `to_a` を内部的に行ってるのかもしれない
というわけで以下を試してみた

```rb
class A
  def to_a
    [:dummy]
  end
end

Array(A.new)
=> [:dummy]
```

**＿人人人人人人人＿**
**＞　[:dummy]  ＜**
**￣Y^Y^Y^Y^Y^Y￣**

なるほどなぁ

つまり `Array(val)` を同値に変換すると

```rb
val.respond_to?(:to_a) ? val.to_a : [val].compact
```

と同じようなコードの可能性が高い。実装読むのは諦めたので間違ってたらごめんなさい

その結果、最初のような想定外の挙動をしたわけだ

## 対処法

結局 `Array(val)` だとエラーが起きるので、とりあえず `[val].flatten` に戻して様子を見ることにした。今回のようなエラーもあるので、ものによっては 方法2. がいい場合もあるが、基本的には 方法1. を選択した方がいいように思う。

それよりも本来は
```rb
class Array
  def self.norm(val)
    val.is_a?(Array) ? val : [val].compact
  end
end
```
って関数定義してこれ使った方が想定外の挙動もなく安定する気はするけどね

以上。
Djangoのモデル作成・一対多・多対多

# モデルの作成
モデルの作成はアプリフォルダーのmodels.pyに記述します。
ここではUserモデルを作成し、名前とメールアドレスのフィールドを持たせたいと思います。
~~~python:User/models.py
from django.db import models


class User(models.Model):
    name = models.CharField(max_length=20)
    email = models.EmailField()
    
    class Meta:
        db_table = 'user'
       
    def __str__(self):
        return self.name
~~~
・Userクラスを作成し、modelsのModelクラスを継承します。
名前のフィールドには文字列を入れたいので`models.CharField`を指定し、メールアドレスには`models.EmailField`を指定する事で自動的にメールアドレスとして正しい値か判断してくれます。
・nameフィールドには入力できる文字数に制限を入れたいので`max_length=20`とし、20文字以内で入力できるようにします。
・`class Meta`の部分でテーブル名を「user」に指定しています。
・`def __str__(self)`では管理画面などで表示されるデータの名前をユーザー名に変更しています。

## データの取得
データベースからデータを取得する方法
~~~python:
#全てのデータ取得
User.objects.all()
#idを指定して一件だけ取得
User.objects.get(pk=1)
#フィルターしたデータを取得
User.objects.filter(name='大谷').all()
#データのフィールドを取得
user = User.objects.get(pk=1)
user.name
~~~

# 一対多のモデル作成
Teamモデルを作成し、Userモデルと一対多の関係を作ります。
「一つのチームに複数のユーザーが所属している」という関係になります。
~~~python:User/models.py
class User(models.Model):
    name = models.CharField(max_length=20)
    email = models.EmailField()
    team = models.ForeignKey('Team', on_delete=models.CASCADE)
    
    class Meta:
        db_table = 'user'
       
    def __str__(self):
        return self.name


class Team(models.Model):
    name = models.ChaField(max_length=30)
    
    class Meta:
        db_table = 'team'
~~~
一対多を作成するのはUser(一の方)に`models.ForeignKey`を指定し、引数にTeam(多の方)と`on_delete`でTeamが削除された場合の処理を指定します。
CASCADE:親オブジェクトが削除されると、そのオブジェクトに紐づいた子オブジェクトも削除される
PROTECT:親オブジェクトに紐づいた子オブジェクトがある場合、親オブジェクトを削除できない
SET_DEFAULT:親オブジェクトが削除された場合、デフォルトオブジェクトに子オブジェクトが紐づく
SET_NULL:親オブジェクトが削除された場合、NULLが設定される
上記以外にも設定可能な値があるので作成するアプリに合わせて適切に設定します。

## データ取得
~~~python:
#UserからTeamを参照
user = User.objects.get(pk=1)
user.team.name
#TeamからUserを取得
team = Team.objects.get(pk=1)
users = team.users_set.all()
#User名とチーム名のor条件で絞り込み(Qをインポート)
from django.db.models import Q
User.objects.filter(Q(name='大谷') | Q(team__name='TeamA').all())
#AND条件
User.objects.filter(name='大谷', team__name='TeamA').all()
#チーム内のユーザーを絞り込み
team = Team.objects.get(pk=1)
team.users_set.filter(name='大谷')
~~~

# 多対多のモデル作成
TeamとUserを多対多の関係にしてみましょう
「複数のチームがあり、ユーザーは複数のチームに所属することができる」という関係になります。
~~~python:User/models.py
class User(models.Model):
    name = models.CharField(max_length=20)
    teams = models.ManyToManyField(Teams)
    
    class Meta:
        db_table = 'user'
       
    def __str__(self):
        return self.name


class Teams(models.Model):
    name = models.CharField(max_length=30)
    
    class Meta:
        db_table = 'teams'
~~~
多対多の関係を作るには`models.ManyToManyField`を指定します。
`ManyToManyField`を指定する事でマイグレーション時に自動でTeamとUserの中間テーブルが作成されます。

# データの取得
~~~python
User.teams.all()
Teams.user_set.all()
#チームにユーザーを追加
user = User(name='大谷')
user.save()
team = Team(name='TeamA')
team.save()
user.teams.add(team)
~~~
チームにユーザーを追加する場合はチームを作成(save())した後`add`で追加する
Assetsに登録した画像がUnassignedになる不具合の対処

# 環境

* Xcode14.1

# 経緯

* Xcodeで新規でAssets.xcassetsにイメージ画像を追加したところ、時間経過あるいはGitのブランチ切り替え時に、登録したImage Setのイメージが登録解除（Unassinned）される現象が発生。
* Web上の既知の不具合報告に同様のケースが見つからなかったため、不具合と解消の経緯を共有する。

# 仮説と検証

* AdobeXDからダウンロードしたイメージ画像ファイルをそのままXcodeに追加したが、ファイル名に[ ]スペースが複数含まれており、ファイル読み込み時に影響を与えているのではと仮説。
* 画像ファイル名から一部、あるいは全ての[ ]スペースを削除、あるいは命名の変更を行い、それぞれAssetsに登録して効果を検証した。

# 結果

* ファイル名の変更により登録解除されなくなるケースと、変わらず登録解除されるケースを確認。

![スクリーンショット 2023-02-04 2.17.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2470935/44e25e3e-74aa-8685-91e0-37a9b23ded41.png)



# 結論

* [ ]スペースを含むファイル名でもUnassignedとならない場合があり、ファイル名の[ ]スペースの有無が本不具合の真因ではない。
* 真因を特定するには至らなかったが、少なくとも本不具合の解決策として、画像ファイル名の変更を試みることが有効であるといえる。（と思う。。）
StreamDeckっぽいものを作る_1

開発言語
Python3系(便利そうなモジュールいっぱいありそうだから)
C#.NET(使い慣れてるから)

こんな感じでサーバとクライアントで分けて作ろうと思う
端末はジャンク品を直したwindowsタブレットでテスト的に作っていく。最終的にはesp32でできるといいなと思ってるけどパーツとかないからいつになることか
![構成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494758/153c0065-548f-aa7e-2ed4-4669fa914b46.png)
クライアント側：基本的にはコマンドをネットワークで飛ばすだけのリモコンっぽい感じでいく。
サーバ側：飛んできたコマンドに応じて各種操作をする

コマンドデータフォーマット
cmd:コマンド名,各コマンドごとのパラメタ名:パラメタ値,各コマンドごとのパラメタ名:パラメタ値・・・
「[cloud_firestore/permission-denied] The caller does not have permission to execute the specified operation.」エラーの解決方法

# はじめに
Flutterエンジニアとして修行中のあんりと申します！
現在入っているプロジェクトで、Firebaseのセキュリティルールに関するエラーに遭遇し、勉強をしたので、アウトプットも兼ねて記事を書くことにしました🚀

## 今回起こった問題
- Firestoreの、qrsコレクションのフィールドの値を更新するため、下記のコードを書き、実行したら処理途中で落ちてエラーが吐かれる。

　↓ 実行したいコード
```Dart:
// qrsコレクションのgroupNameを更新する
  Future<void> updateQrInfoGroupName(String groupName) async {
    final qrNumber = await fetchQrNumberString();
    final docRef = qrsReference.doc(qrNumber);

    // ここで落ちてエラーが吐かれる
    await docRef.update({'groupName': groupName});
  }

```

　↓ 吐かれるエラー

```
[cloud_firestore/permission-denied]The caller does not have permission to execute the specified operation.
```

## エラーの原因調査
-  「Storage」のセキュリティルールが下記のようになっていることを確認。
![スクリーンショット 2023-02-01 19.51.27 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2700334/88b9870f-827a-2235-ed68-b37d957b42c8.png)

- 一番下の行について
    `allow read, write: if request.auth != null;`
     →「authにログインしてなければ読み書きできない（=authでログインしてれば読み書き可能）」という内容で書かれている。
     ただ、authでログインをしている状態でアプリを動かしているので、エラーが出る謎が深まる。

## エラーの原因となってたセキュリティルールは、「Firestore Database」の方にあった！
- 「Storage」ではなく「Firestore Database」のセキュリティールールを確認！
　　<img width="300" alt="スクリーンショット 2023-02-04 17.53.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2700334/2aa975dc-fb2d-4c9c-be72-1c0730f44ae7.png">

- 　この中の、qrsコレクションへのセキュリティルールの箇所 ↓ 
    ```Dart:
  match /qrs/{gr} {
    // authでログインしてればドキュメント作成と、データ取得は可能
    allow read, create: if request.auth != null;
      // updateとdelete（削除や更新）は許可されていない
    allow update, delete: if false;
  }
    ```
　　ここでupdateが許可されていないのが原因だった！　　
　　なので、updateを許可するように修正が必要。

## 解決 - セキュリティールールを修正・公開
1. updateの場所を下記のように変更
    ```Dart:
      match /qrs/{gr} {
        allow read, create, update: if request.auth != null;
        allow delete: if false;
      }
    ```
2. 下記を参考にしてルールプレイグラウンドでテスト
    https://firebase.google.com/docs/rules/simulator?hl=ja
3. テスト実行 →「シミュレートされた読み取りが許可されました」と出て、テスト成功
4. 「公開」で修正後のセキュリティルールを反映
5. 反映後、シミュレーターを動すと、エラー吐かずに無事にフィールドの値が更新できた！
    #### 解決🎉🎉

# おわりに
まだ知識と経験が浅いため、誤った箇所などありましたら、ご意見やご指摘などいただけたら幸いです！
そしてもしこの記事がどなたかのお役に立てたら嬉しいです！
読んでいただきありがとうございました！🙇‍♀️
Pythonでfirestore.client()に型をつける

[ドキュメント](https://firebase.google.com/docs/firestore/quickstart?hl=ja)だと
```
db = firestore.client()
```

のように記載してある。

しかし、firestore.client()は返り値の型を固定していないのでAny型となる。

db.　のようにコード上で記載しても「お前Anyだから何出していいかわかんねぇよ」となる。

---

型をつけるために

1. importする

```
from google.cloud.firestore_v1.client import Client
```

2. 型をつけてあげる

```
db: Client = firestore.client()
```


これでdb. と書けば色々頼れる関数が出てくるはず。


---

追記

- エラーハンドリングはご自由に。どんな時も必ずClient型で帰ってくるわけではないので。
Salescloud Consultant 学習メモ②

<h5>Web to Lead</h5>
WebフォームからSFにリードレコードを自動で作成する機能

<h5>自動レスポンスルール</h5>
外部のWebサイトからの登録者にメールで自動送信する機能

<h5>割り当てルール</h5>
取り込まれたリードに所有者を割り当てる機能

（割り当てルールの対象：ユーザ、キュー）

<h5>リードの取引開始</h5>
見込み客から取引先へデータ移行する

「取引先」、「取引先責任者」、「商談」への作成/編集権限が必要

<h5>項目の対応付け</h5>
リードのカスタム項目の値を移行先に引き継ぐ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995724/6affee49-6632-2ad7-3b1b-5b59fc64b442.png)



<h3>リードの品質向上</h3>
<h5>・スコアリングの項目作成
<h5>・必須項目</h5>
①項目作成時必須項目の設定

②ページレイアウトで必須項目の設定
<h5>・入力規則</h5>
<h5>・HTML,JAVASCRIPTによるチェック</h5>
<h5>・取引開始時の項目の対応付け
<h5>・SalesCloud Einstein


<h3>キャンペーン</h3>
<h5>・キャンペーンインフルエンス<h5>

ROI確認、影響度の確認に使われる

どのキャンペーンが商談の成立に貢献したのか確認する機能
主キャンペーンソース：キャンペーンインフルエンスの中一番効果が高いキャンペーン


<h5>・キャンペーンの自動関連付け</h5>
取引責任者ロール使用　→　取引責任者がキャンペーンメンバーとなったキャンペーンを自動的に商談に割り当て

<h5>・キャンペーンメンバー</h5>
キャンペーンの参加者及びTarget

<h5>・キャンペーン階層</h5>
キャンペーンをグループ化して分析に使う機能


<h5>・売上予測</h5>
Lightning Experienceでデフォルトで有効化
PythonAnywhereでFlaskアプリを実行したときに生じる「Error running WSGI application」エラーの対処法

初めての投稿なので、読みにくいかもしれませんがご了承ください。

# エラー
```:error.log
2023-02-03 14:55:46,616: Error running WSGI application
2023-02-03 14:55:46,617: OSError: [Errno 98] Address already in use
```
PythonAnywhere上にFlaskアプリをデプロイして実行したときに、上のような`Address already in use`というエラーが起きて解決するまで時間がかかりました。

ネットで調べたlsofでプロセスを確認することや、killコマンドを使うなど試しましたが、全て上手くいかず…。

# 解決策
main.pyでFlaskのサーバーを起動する書き方が問題でした。

```python:main.py(編集前)
app.run(debug=True, host='0.0.0.0')
```
```python:main.py(編集後)
if __name__ == '__main__':
  app.run(debug=True, host='0.0.0.0')
```
以前、授業では「`if __name__ == '__main__':`の部分を消す」と習いましたが、これが無いと先ほどのAddress already in useが表示されてしまうようです。
このif文を書くことで、無事にサーバーの起動ができました！

## 余談
授業で使った環境はReplitだったのですが、試しにReplitでもif文を付けてからサーバーの起動を試してみたら、こちらもちゃんと起動が出来ました。
だとすると、なぜif文を外すように指示をしたのでしょうか…。今度先生に質問してみることにします。
[Prisma]PostgreSQLで大文字小文字を区別せずuniqueな制約をつける

prisma: 4.7.1
db: PostgreSql(supabase)

prisma使いのみなさんこんにちは。
PostgreSQLでは「大文字」と「小文字」の区別をつけてくれます。
`Abc == abc -> false`

しかし、unique制約を付ける際に「大文字」「小文字」の区別つけずに重複を許したくない時はあるでしょう。
`Abc == abc -> true`

幸運なことにpostgreでは[citext型](https://www.postgresql.org/docs/current/citext.html)というものが用意されています。これをprismaで指定してあげれば実現できるでしょう。


# 実装
```js:schema.prisma

generator client {
  provider = "prisma-client-js"
  previewFeatures = ["postgresqlExtensions"] // 追加
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
  extensions = [citext] //追加
}

model User {
  email String @unique @db.Citext
}
```

# 参考
公式に載っているので正確にはそちらを参照してください。

https://www.prisma.io/docs/concepts/components/prisma-schema/postgresql-extensions