OmniAICreator/Qiita-1.07M huggingface dataset:
GitHub REST APIのトークン取得手順

# GitHub REST APIトークンの作成画面への行き方
まず、GitHubの公式ページにアクセスしましょう。
https://github.co.jp/
その後、以下の手順でAPIトークンの作成画面に移動します。
1. ログインしたら、右上にある自分のアイコンをクリックし、メニューバー下から二つ目の「Settings」をクリック。![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851811/0ca347d6-36d7-1fcf-39f9-1f800fcb81b4.png)![キャプチャ4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851811/0822f0bf-ea4c-e334-d12d-63d00909a1cc.png)


2. 画面左のメニューバー一番下の「Developer settings」をクリック。![キャプチャ3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851811/5bc53525-d7c3-093f-2db8-4757547e3c6f.png)
3. Developer settingsの画面が表示されるので、画面左のメニューバー一番下にある「Personal access tokens」の「Fine-grained tokens」をクリック。![キャプチャ5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851811/b952a6eb-489f-4278-2e20-918ea2c4b7fa.png)

4. Generate new token (beta)」をクリック。![キャプチャ6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851811/99b08aee-60c2-f726-c618-e22de9e345d1.png)
すると、「New fine-grained personal access token」画面に移動します。![キャプチャ7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851811/b019b67b-92b4-9d2d-ebc1-11d7fc7789de.png)
ここで、作成するトークンの詳細を作っていきます。

# GitHub REST APIトークンの作成手順
ここからは、トークンの作成の手順です。
1. 「Token name」で名前を決めます。正直決めなくても良いです。適当に付けましょう。![キャプチャ8.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851811/145b3881-8bad-3845-4481-0d6d07493aa0.png)

2. 「Expiration」でトークンの期限を決めます。その瞬間しか使わないなら、「7 days」でいいでしょう。![キャプチャ9.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851811/c23c92bd-a0a0-7877-7774-6e29a5a52c18.png)

3. 「Description」でトークンの説明を書きます。Token nameと一緒で、無くても良いです。![キャプチャ10.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851811/a7d3c06c-0c7e-67d7-d25e-a6365f77e42c.png)

4. 「Resource owner」でこのトークンの所有者を決めます。![キャプチャ11.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851811/4d849039-7ee9-acac-cf03-8f47eba94e98.png)

5. 「Repository access」で、トークンを使って接続するリポジトリを決めます。![キャプチャ12.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851811/536201f1-01bd-af9d-4063-9e6dece0b289.png)
無難に「Public Repositories (read-only)」を選んでおきましょう。
6. 「Permissions」でトークンに権限を付与できます。![キャプチャ13.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851811/ce3ee552-2ae2-7838-4af9-eb01dcc7968d.png)
詳しくはこちらのページへ。https://docs.github.com/en/rest/overview/permissions-required-for-fine-grained-personal-access-tokens?apiVersion=2022-11-28
7. 「Overview」でトークンの概要を確認します。![キャプチャ14.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851811/3de18c7b-3826-3ca6-588d-e154595bdea0.png)
漏らしがないようにしましょう。一度作ったトークンは設定の変更ができず、トークンを作り直す必要があるので、一回はチェックしましょう。
8. 緑色の「Generate token」ボタンを押して、トークン生成完了です。![キャプチャ15.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851811/e3b83f0b-4bfc-4ba4-b10f-65ce449c90f4.png)

9. 気を抜かないでください。「Generate token」ボタンを押した後、今作ったトークンのコードが表示されます。このコードは、この瞬間しか表示されず、後からは確認ができないので、必ずメモをしておきましょう。忘れたら作り直しです。![キャプチャ16.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851811/9086d072-cfcc-9664-3068-d97c17785f74.png)



以上でトークンの生成は終了です。GitHubを効率よく使っていきましょう。
k3sにNginxのpodを立てる

# k3sを使ったNginxのpodの立て方
今回，Nginxのリバースプロキシサーバを立てる機会があったため，その手順をここに記す．
## k3sのインストール
初めに，podを立てるための土台となるk3sをインストールする．これにはk3sが提供するインストレーションスクリプトを次のように実行する．
```
$ curl -sfL https://get.k3s.io | sh -
```
正常にインストール出来れば次のようなkubectlコマンドが通る．
```
$ sudo kubectl get nodes
NAME          STATUS   ROLES                  AGE     VERSION
```
## helmの準備
helmのインストールを行う．helmもインストレーションスプリクトが存在するため，これを実行する．
```
$ curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
```
次にhelmのレポジトリを追加する．今回レポジトリ名はmy-repoとした．
```
$ helm repo add my-repo https://charts.bitnami.com/bitnami
```
## Nginxのpodをインストール
以下を実行し，helmを使用してNginxをインストールする．
```
$ helm install my-release my-repo/nginx
```
## podを立てる

最後にpodの立ち上げを行う．
```
$ helm upgrade my-release my-repo/nginx -f nginx-values.yaml
```
以下のような応答が返ってくれば正常に立てることが出来ている．
```
Release "my-release" has been upgraded. Happy Helming!
NAME: my-release
LAST DEPLOYED: Mon Jan 16 10:46:57 2023
NAMESPACE: default
STATUS: deployed
REVISION: 2
TEST SUITE: None
NOTES:
CHART NAME: nginx
CHART VERSION: 13.2.21
APP VERSION: 1.23.3

** Please be patient while the chart is being deployed **
NGINX can be accessed through the following DNS name from within your cluster:

    my-release-nginx.default.svc.cluster.local (port 80)

To access NGINX from outside the cluster, follow the steps below:

1. Get the NGINX URL by running these commands:

  NOTE: It may take a few minutes for the LoadBalancer IP to be available.
        Watch the status with: 'kubectl get svc --namespace default -w my-release-nginx'

    export SERVICE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].port}" services my-release-nginx)
    export SERVICE_IP=$(kubectl get svc --namespace default my-release-nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    echo "http://${SERVICE_IP}:${SERVICE_PORT}"
```
## 参照
[K3s のインストール手順 | hassiweb's memo - GitLab](https://hassiweb.gitlab.io/memo/docs/memo/k3s/k3s-installation/)

[NGINX Open Source packaged by Bitnami - GitHub](https://github.com/bitnami/charts/tree/main/bitnami/nginx)
うまくいかない原因が画像データ不足と感じたときに手っ取り早く９０度回転で４倍にデータを増やす

# サンプル数が少ないとうまく結果を出せない可能性がある

### 正方形の画像かつ回転等を行っても大丈夫なデータに限るが、画像データの水増しを行ってみる



## 使用ライブラリ
```
import numpy as np
import glob
import os
from matplotlib import pyplot as plt
import cv2
```

## プログラム
```
#今回はGoogleコラボを使うのでこの一文を入れる
from google.colab import drive
drive.mount('/content/drive')


#指定した場所から取得
true_train_img=glob.glob(os.path.join("/content/drive/MyDrive/mvtec/tile/train/good", '*'))

#取得したアドレスの確認
print(true_train_img)

#枚数の確認
print(len(true_train_img))
lensize=len(true_train_img)

#枚数分
for i in range(lensize):
    #一枚に対しての処理
    #９０度、９０度、９０度で一回転するので３になる
    for j in range(3):
        
        img=cv2.imread(os.path.join(true_train_img[i]))
        
        #保存先の指定 最後/としないとファイル直下に大量の画像が入るので注意
        savepath='/content/drive/MyDrive/mvtec/tile/train/mizumasi/'
        zero_i = "{0:03d}".format(i)
        one_i="{0:01d}".format(j)
        
        #アドレスの指定と数字を組み合わせ
        new_name =  savepath+zero_i+one_i+".png"
        for k in range(j):
            img=cv2.rotate(img,cv2.ROTATE_90_CLOCKWISE)
        #書き込み処理
        cv2.imwrite(new_name,img)
        


```

この処理を行う事で、１枚→４枚になるのでデータは確保できるはず。
しかしながら上下左右などデータを変えてしまうと成立しないようなデータは使用するべきではないのでちゅうい


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079535/32161312-f9fa-1970-53b4-59eb479f9fdd.png)

ドライブ上ではこのような配置になる。goodは元の画像mizumasiは回転後の画像が入る。画像を１フォルダで一緒にしてしまうと元データが分かりにくくなるので分けている。


```
true_mizumasi_train=glob.glob(os.path.join("/content/drive/MyDrive/mvtec/tile/train/mizumasi" , '*'))
```
上のような一文を学習用プログラムに入れることで、取得した画像をプログラム上で追加できる。
Ubuntu 22.04 LTS Server の公開鍵認証方式によるSSH接続の方法

# 目次
[1.仕様](#仕様)
[2.キーの作成](#キーの作成)
[3.キーの設定](#キーの設定)
[4.設定ファイルの編集](#設定ファイルの編集)

# 仕様
SSH接続にはパスワード認証方式と公開鍵認証方式の2つがあります。
公開鍵認証方式とは
> 電子署名の応用で、秘密鍵の所有者しか正しい署名が作れないことを利用し、署名の正しさを公開鍵で検証してもらうことで、確かに所有者であることを確認してもらいます。
このような使い方ですから、秘密鍵は利用者本人以外に漏らしてはいけませんし、公開鍵は予めサーバに登録しておく必要があります。
これが本人確認になっているということです。

https://qiita.com/angel_p_57/items/19eda15576b3dceb7608#%E5%85%AC%E9%96%8B%E9%8D%B5%E8%AA%8D%E8%A8%BC%E3%81%AE%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8

特にこだわりが無ければ、公開鍵認証方式を使うことをお勧めします。

# キーの作成
まずは下記のコマンドを実行し、キーを作成します。

**実行コマンド**
```
$ ssh-keygen
```
**実行結果**
```
Generating public/private rsa key pair.
Enter file in which to save the key (/home/ubuntu/.ssh/id_rsa):
```
もしキーの場所を変更する場合はここで変更してください。そのままで良い場合は何も入力せずEnterを押してください。
```
Enter passphrase (empty for no passphrase):
Enter same passphrase again: 

```
パスフレーズを設定する場合はここで設定してください。基本的にセキュリティーが上がるので設定しておくと良いでしょう。

```
The key fingerprint is:
SHA256:pqxX1cEHDIRsN31uVPPaxeBFrHjss7BbP9aNMIQnZZc ubuntu@example.com
The key's randomart image is:
+---[RSA 3072]----+
|       . oo=...*+|
|        + o B.E++|
|       . . * X..+|
|          + = *o.|
|        S. + +. .|
|     . o.   + o  |
|      o.     =.+o|
|     ..     ..o+o|
|    ..      ... o|
+----[SHA256]-----+

```
次に、キーを確認します。デフォルトの設定ですと、ホームディレクトリ内の.sshに保存されています。
**実行コマンド**
```
$ ls .ssh
```
**実行結果**
```
id_rsa  id_rsa.pub
```
id_rsa は秘密鍵、id_rsa.pub は公開鍵のファイルです。
id_rsaはクライアント側に保存しましょう。
これでキーの作成は終わりです。

# キーの設定
まずは、id_rsa.pubをauthorized_keysに名前を変更します。
**実行コマンド**
```
$ mv ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys
```

次に、authorized_keysのパーミッションを600に変更します。
**実行コマンド**
```
$ sudo chmod 600 ~/.ssh/authorized_keys
```
これでキーの設定は終わりです。

# 設定ファイルの編集
設定ファイルを変更する前に公開鍵認証方式で接続できるか確認しましょう。
確認が終わりましたら、設定ファイルを変更しパスワード認証方式を無効にします。
**実行コマンド**
```
$ sudo nano /etc/ssh/sshd_config
```
``` command:/etc/ssh/sshd_config
. . .
PasswordAuthentication no
. . .

```
変更が終わりましたら、SSHを再起動します。
**実行コマンド**
```
$ sudo systemctl restart ssh
```

これで公開鍵認証方式によるSSH接続ができました！
[TS/JS] Logical Assignment Operatorの挙動

挙動のメモ書き

- [TS Playground](https://www.typescriptlang.org/play?#code/PQKhCgAIUgZB7A5gSwMYEMA2kCCBnPZRAOwFsBTYgF0gHkAHcgJ3SvibyhGHHAG8okUBEiiYCFBmw4AcgBFI6AkWLlS1QdEiaYAAUzJiAa0gALKlXp4AXMGAATcgDdymeIyYA6UvABeyTEx0T3ZEYEoAWgBVAGUHeFQ8YAB1cgAjYAApdCd0GNQmZHoqYAAlcgAzZkpUcmAGZlZ2JIk0LAB9WTl2pUISCg1RaB5RVHhiPBo3REgAXkgACk9l9CZEG0ViAE8AbQBdAEo5gD5IMYn4THJPaYWAIgBiLruAGkhlz1X1g4BuXlErjR0ABGOaQACuxEcFUM5Hsf1EIMgADJkfM7lRTMg8JBsZAZLQACqQVQAd0guUw4PIdx+QmAkEAvBuAUT3ALAEgAEyQDwf4JbnxFKCAL6-f6QQGQNKg9GYvF4+hMZwUrDU2mCCUotGQDFYnF4smKqk0ul2JmAMT3WYAhMm5AKQCz5aqFfx55BoqElmpVo1BqKl2txOIJxL1lOVRoZLI5VtFNr5rsgDvAAt4AlEwh0cCQbWwtFKimUJDUgzE2iGegMxjMFistgczlc7mY3j8ASCITW4WI0Ti9gSSVSGWyuXyhWKZUq1WItXqHiaHGArSk7WzPTzZEoVB0IzO40mUZm8yWKzWG3Q232R1mp3OeEu11uj2zr3eh++joBzv5YMh0Nh8MESIAPv+PoyjiQZKjS9Kmhaka8h+8ZOjQarATqOJygqwaGqqoKAchfr4kSJLkOSGG0pB4Zcjy0bioKwoIWcbp3B69GQDhmrSihhHEeBpHGoyZqWpRiC2sx8aJvwgipiW+LgoE2KmFuWDkHgqCGDMvQqAM65SWm+iGCYG6CFeUxIGCB6fEe1ibLshwnFuFxXDcNqPDIUSwLAACSMQABKPh8Xx4LRb5Am6X6VD+CIfgA-JFuG6kR+rKmR-EwVRSLwUF1FglqIGQGhTgJZhohqtFsX+gRYEGjxYZshR1pCXaNGvqK76xuiTGxiVbG+niAacQVVVMjVKX1SJwoCkAA)
```ts
/**
 * Logical Assignment Operators
 */

{
  /**
   * Logical AND assignemnt
   * 
   * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND_assignment
   */
  const log = (...args: any[]) => console.log("#AND", ...args);

  let a1 = undefined;
  a1 &&= "this is NOT new value"; // 🙅‍♀️
  log({ a1 });

  let b1 = "this is prev value";
  b1 &&= "this is new value"; // 🙆‍♂️
  log({ b1 });

  let c1 = "";
  c1 &&= "this is NOT new value"; // 🙅‍♀️
  log({ c1 });
}

{
  /**
   * Logical OR assignemnt
   * 
   * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_OR_assignment
   */
  const log = (...args: any[]) => console.log("#OR", ...args);

  let a1 = undefined;
  a1 ||= "this is new value" // 🙆‍♂️
  log({ a1 });

  let b1 = "this is prev value";
  b1 ||= "this is NOT new value"; // 🙅‍♀️
  log({ b1 });

  let c1 = "";
  c1 ||= "this is new value"; // 🙆‍♂️
  log({ c1 });
}

{
  /**
   * Nullish coalescing assignment
   * 
   * @link 
   */
  const log = (...args: any[]) => console.log("#NULLISH", ...args);

  let a1 = undefined;
  a1 ??= "this is new value" // 🙆‍♂️
  log({ a1 });

  let b1 = "this is prev value";
  b1 ??= "this is NOT new value"; // 🙅‍♀️
  log({ b1 });

  let c1 = "";
  c1 ??= "this is NOT new value"; // 🙅‍♀️
  log({ c1 });
}

```
加速度センサから得られた値を移動距離に変換

## 今回使用した実験機器
- ESP32：Wi-Fi と Bluetooth を内蔵しており,低コストで低消費電力なマイクロコントローラである.

- BMX055：9 軸 (加速度 3 軸,ジャイロ 3 軸,磁気コンパス3 軸) センサを扱いやすいパッケージでまとめられたセンサモジュールである.

## 加速度センサから移動距離に変換する
加速度センサから取得した値は，時間と加速度のx, y, zである．それらの値が入ったcsvファイルを読み込んで，移動距離に変換している．今回は，加速度センサz軸のみ使用して計算を行っている．
- 加速度センサから値を取得するプログラム
https://github.com/cdsl-research/C0A20109/blob/8bdf883939ff1123ec5b66a6bd2332fc5da78cb9/accl_log.py


```python:accl_distance.py
from csv import reader
import math

#csv読み込み
def csv_file(file):
    with open(file, 'r') as csv_file:
        csv_reader = reader(csv_file)
        data_header = next(csv_reader) #一行目を出力
        data = list(csv_reader)
    return data
  
#計測時間処理
def time(data):
    elapsed_time = 0
    time_list = []
    elapsed_time_list = []
    
    for i in range(len(data)-1):
        time_list.append(float(data[i+1][0]) - float(data[i][0]))
        elapsed_time += time_list[i]
        elapsed_time_list.append(elapsed_time)
        #print(elapsed_time[i])
    return time_list, elapsed_time_list

#z軸データ処理
def accl_z(data):
    z_list = []
    abs_z_list = []
    for i in range(len(data)-1):
        z_list.append(float(data[i+1][3]) - float(data[0][3]))
        abs_z_list.append(math.fabs(z_list[i]))
        #print(z[i])
        #print(absolutely_z[i])
    return z_list, abs_z_list

#速度計算
def speed(data, abs_z, time):
    speed_list = []
    for i in range(len(data)-2):
        speed_list.append(((abs_z[i] + abs_z[i+1]) * time[i]) / 2)
        #print(speed[i])
    return speed_list

#移動距離計算
def distance(data, speed, time):
    distance_sum = 0
    distance_list = []
    distance_sum_list = []
    for i in range(len(data)-3):
        distance_list.append(((speed[i] + speed[i+1]) * time[i]) / 2)
        distance_sum += distance_list[i]
        distance_sum_list.append(distance_sum)
    return distance_sum_list

file = "accl.csv"
data = csv_file(file)
time, elapsed_time = time(data)
z, abs_z = accl_z(data)
speed = speed(data, abs_z, time)
distance_sum = distance(data, speed, time)
```

## [実験結果] 移動距離の推移
これは，実際の距離が15mの状態を歩行した実験である．はじめに5秒間停止し，15m歩行して，再び5秒間停止している．

![output.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2854781/8e303e2b-f727-c68a-dc20-bdf1a9e70ced.png)

結果：12.6[m]

## 加速度センサから取る値の注意点
身体に加速度センサを取り付ける方法によって加速度の値の変動が大きいので，注意が必要です．(上記の実験は，腰にテープで取り付けた際の結果)
paiza.ioでelixir その162

# 概要
paiza.ioでelixirやってみた。
大量のtaskやってみた。

# 参考にしたページ

https://qiita.com/gr8distance/items/2eabe41744ae2b3ab277


# サンプルコード

```
:erlang.system_info(:process_limit)
|> IO.inspect

defmodule Experimental do
	def run(n) do
		process_limit = :erlang.system_info(:process_limit)
		IO.puts "process limit is #{process_limit}"
		1..(process_limit - n)
		|> Enum.map(fn i ->
			Task.async(fn ->
				i * i
			end)
		end)
		|> Enum.map(& Task.await(&1))
		|> IO.inspect
	end
end
	
Experimental.run(80000)


```

# 実行結果

```
262144
process limit is 262144
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324,
 361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961, 1024, 1089,
 1156, 1225, 1296, 1369, 1444, 1521, 1600, 1681, 1764, 1849, 1936, 2025, 2116,
 2209, 2304, 2401, 2500, ...]
```

# 成果物

https://paiza.io/projects/Ghb77JW2GGmbzNbfT6x1Vw


以上。
【CakePHP】入門記事

# 0. はじめに
## 0-1. 全体の流れ
> [1.教材](#1-教材)
> [2.基礎](#2-基礎)

## 0-1. TL;DR
- CakePHPの教材や基礎参考リンク集まとめ

## 0-2. 
# 1. 教材
https://book.cakephp.org/4/ja/tutorials-and-examples/blog/blog.html

https://book.cakephp.org/4/ja/tutorials-and-examples.html

https://book.cakephp.org/3/ja/tutorials-and-examples.html

https://dotinstall.com/lessons/basic_cakephp_v2

https://dotinstall.com/lessons/basic_cakephp

https://www.amazon.co.jp/dp/4798048577

https://www.amazon.co.jp/dp/4798054097


# 2. 基礎
https://book.cakephp.org/4/ja/contributing/cakephp-coding-conventions.html

https://qiita.com/nanatsu/items/9b51190ecc1c0138a96b

https://qiita.com/nekoneko-wanwan/items/9d792f46d570a45e4782

https://qiita.com/nanatsu/items/eec31c62617a48cbdff2

https://qiita.com/humuhimi/items/b43eeef355c1c8a9b31b

https://qiita.com/kazu56/items/88c67caf819b601cedb6

https://zenn.dev/yu7/articles/f77572925c6fa8

https://tt-computing.com/cake4-install

https://www.sejuku.net/blog/66939

https://qiita.com/H-Toshi/items/1a942e5866bc644bb163

https://qiita.com/geechlife/items/4f7d19bd60b797ebb087
技術士二次試験の答案用紙

# 作った
令和4年度の受験時の色とかフォーマットに似せて作りました。
印刷して手書きで練習するのを想定しています。

# 
## １
https://drive.google.com/file/d/1-85VCPBfyCydSBHn3-a9zfVot2-jttf_/view?usp=sharing

## ２－１
https://drive.google.com/file/d/1-AYtCKVle2DaVBhM_NyX3W25CLn9qyOq/view?usp=sharing

## ２－２
https://drive.google.com/file/d/1-8lxWodWryE5yZWzTjhj74G6pV_QUnRO/view?usp=sharing

## ３
https://drive.google.com/file/d/1-A_wJgdrar325xe_VtfWpoSrT2F8cAj4/view?usp=sharing
Viva Connections アプリを利用してTeamsからホームサイトを表示する

Microsoft Teams のサイドバーにSharePointサイトをピン止めしたい！という要望は結構ございまして、Developer PortalでContent URLをSharePointサイトにするカスタムアプリを生成することで実現可能です。
ところが、いつの日からかこの方法が「非推奨」になってしまったんですね。

じゃあどうすればいいんだ、ということで管理者向けにはなってしまいますが、特定のサイトを簡単に（？）サイドバーにピン止めする方法を紹介いたします。具体的にはViva Connectionsというファーストパーティアプリを利用します。

# サイトを作る

まあ、サイトを表示するわけですからサイトを作るのですが…。注意点としてこのサイトは**コミュニケーションサイト**である必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/dc985e05-7259-d97b-1e0c-ab1a4f0584b0.png)

# そのサイトを「ホームサイト」に指定する

これは SharePoint 管理センターでの操作が必要です。[設定]->[ホームサイト]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/7d8ca726-023e-46d8-5044-d04f33f666d7.png)

URLを入力します（選択式になっていないのがつらい・・・）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/0b90581b-4ebf-b171-925b-1ff771945d11.png)


# Teams で Viva Connections を使えるようにする
なぜかデフォルトで Viva Connections の Teams アプリが無効になっていることが多いです…。
Teams 管理センターで[Teams のアプリ]->[アプリを管理]より Viva Connections を探してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/28e9b65d-67d1-60db-fe76-76f735068254.png)

状態が許可済みになっていればOKです。ブロックになっていた場合、許可ボタンをクリックします。

# Teamsで Viva Connections を使ってみる
Microsoft Teamsを起動し、アプリから Viva Connections を探します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/550bd954-249a-24d6-b615-e58ce6b44ba7.png)

[追加]すると先ほどのコミュニケーションサイトが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/ea3318ae-dba5-a5fc-c551-0dcbc40f5c6d.png)

# ユーザーに配布する
この設定を組織内全員に適用することで、全員がホームサイトになっているページに簡単にアクセスできるようになります。

Teams 管理センターより[Teamsのアプリ]->[セットアップポリシー]を選択し、適用するポリシー（グローバルなど）を選択します。

インストール済みアプリの項目から[アプリを追加]をクリックします。Viva Connections を探して追加ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/b3ee150c-a3b4-0e25-e33f-139d5f0801e3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/dcf8ad3c-3c97-5f27-e429-662152f4e76b.png)

ピン止めされたアプリの[アプリを追加]をクリックして Viva Connections を追加し、いい位置にピン止めします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/0767fffd-f0e3-1908-56bf-7de4e31fe4c7.png)


Teams から確認してみましょう。Viva Connections よりホームサイトが表示されました。（反映に時間はかかります）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2095776/b06309af-a12c-d089-7bf5-67ff0b582807.png)

全社展開など範囲が広い場合は Developer Portal よりこちらの方法のほうがよさそうです。
CVE-2022-23529のjsonWebTokenに関する脆弱性について

# 概要

[CVE-2022-23529](https://github.com/advisories/GHSA-27h2-hvpr-p74q) 
js のライブラリ jsonWebTokenに関する脆弱性が報告された。
このライブラリは jwt の署名の検証などに用いられている。

# 脅威の内容

詳細な説明に関しては[こちら](https://unit42.paloaltonetworks.com/jsonwebtoken-vulnerability-cve-2022-23529/)を参考にしていただきたいが、ざっくりとはこう。

jsonWebToken　をもとに　jwt の署名の検証をするときにpemファイル(公開鍵)の値を入れる引数がある。
そこに不正なオブジェクトを挿入すれば不正に突破される模様。

# 所感

個人的にはこの脅威に対して急ぎ対応する必要はないかなと思いました。
基本的にはjwtの署名の検証における公開鍵にあたる引数はバックエンドからのみ指定できるように実装されていて、てかそうなっていないと元から不正アクセスされてもおかしくないという代物。
つまりこの攻撃ができるような実装になっていたらそもそもこの脆弱性を直しても同様の攻撃ができてしまうので、実装自体を見直すべき。

# 最後に

あくまで個人の感想なので、皆さんの参考程度になれば幸いです。
ご指摘等あればお願いします。
TeraTermのマクロでコマンド実行

# 概要

実質的に下記記事の続きとなります。

https://qiita.com/waokitsune/items/6dcc80676a66fd8751e4

この記事ではTeraTermマクロの基礎知識は割愛。

# やり方

Windows10のPCに接続する前提です。

```:ttlファイルの中身
;ログイン情報
USER_NAME = 'おなまえ'
USER_PASSWORD = 'おぱすわーど'
HOST = '接続先'

;ログインコマンド生成
login_command_ = HOST
strconcat login_command_ ' /ssh /auth=password /user='
strconcat login_command_ USER_NAME
strconcat login_command_ ' /passwd='
strconcat login_command_ USER_PASSWORD

;ログイン実行
connect login_command_

;『コマンドが入力できる状態まで待つ ⇒ コマンド実行』という同期処理となるよう、wait。
;接続先がWindows10の場合は『#』ではなく空文字を待つ。
wait ""

;コマンド実行
sendln "ipconfig /all"
```

コマンド実行の前に ```wait``` で『接続先からの応答が画面出力されるまで待つ』ことがポイント。
んで、『どんな値』が画面出力されるまで待つかは接続先OSによって異なるのもポイント。

```sendln``` でコマンド実行。

# コマンド内にダブルクオテーションがある時

下記のようにダブルクオテーションを前に付けてエスケープしてあげる。

```
sendln "sc query ""MariaDB"""
```

# 参考サイトさん

https://nwengblog.com/teraterm-command/

# バージョン

Windows 10 Pro 21H2 OSビルド 19045.2364
TeraTerm 4.106
THETA Xで360°動画をトリムする方法

こんにちは。どうでもいいですがTHETAとQiitaってなんか響きが似てませんか。
@Esperna です。今回はTHETA Xで360°動画をトリムする方法について書きます。
結論を書くと普通の動画と同じようにffmpegで360°動画をトリムできました。

# 背景
2022年に水中撮影用にTHETA XとSTAYTHEE（浮力調整具）を買いました。
いざ水中動画を撮ってみたところ、５分の動画で2GBとなかなかのサイズです。
スマホやPCに転送して保存しますが必要なシーンだけ切り取って容量を節約したいなと。
そこで、THETA+ という[公式の編集アプリ](https://theta360.com/ja/about/application/edit.html)を見てみると、動画の編集ができそうです。

# 360°動画とクロップ動画

先程のTHETA+の説明によれば、360°動画とクロップ動画という言葉があるそうで。
360°動画は再生中にぐりぐりと回転させることができますが、
クロップ動画は360°動画から平面的に切り取ったもので、
ぐりぐりと回転させることができません。
私が切り取りたいのはクロップ動画ではなく360°動画です。
でも、THETA+ の説明(2023/01/11現在)には「編集後も動画をぐりぐりと回転させることができます。RICOH THETA Vで撮影した4K動画の360°空間音声情報を保持したまま、書き出しが可能です。」とあり、THETA Xは未対応っぽいです。THETA Xの動画をTHETA+で編集した後360°動画で書き出す方法が分かりませんでした。

# ffmpeg

なので、スマホアプリやPCアプリを探しましたが、有料のアプリを買いたくなかったのと、
出所の分からないツールを使いたくなかった（ウイルスとか怖い）ので、
実績のあるオープンソースのフリーのツールを使うことにしました。
[ffmpeg](https://ffmpeg.org/) は動画・音声の変換ツールです。

やりたいことは360°動画で必要なシーンだけ切り取って容量を節約することです。
以下のようにしてffmpegを使います。

1. THETA XからPCに動画を取り込む
USBをPCに直接挿して取り込むか予め360°動画を転送したスマホからAirDropで転送します

1. 360°動画をPCで再生して切り取りたい尺を確認する
何秒から何秒までの部分を切り出したいか確認します。
ここでは1:43から1:52までの9秒を切り取ることにします。
![screenshot360.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244232/7ba4f010-0fea-e0d7-6f34-f55800cad096.png)

1. ffmpegのコマンドを実行する

```
ffmpeg -ss 103 -i R0030004.MP4 -t 9 kobudai.mp4
```
* `103`は開始時間
* `R0030004.MP4`は切り取りたい動画
* `9`は切り取りたい時間
* `kobudai.mp4`は出力動画

サイズは元が805.8MB(1分59秒)だったのが22MB(9秒)になりました。
ちなみに切り取った360°動画は[こんな感じ](https://theta360.com/m/qFprzTenbk2SIQNoklk2tNZdA?utm_source=ricoh_twitter&utm_medium=social)。
コーデックやカラープロファイルが変わってるのが気になったので、
後でよく調べてみようと思います。
Power Apps でギャラリー内のチェックボックスを一括でリセットする


# はじめに

Power Apps でアプリを作成していると、ギャラリー内に存在するチェックボックスを一括でリセットしたい場合があります。

例えば、以下のような働き方を共有するアプリにて、一括で働き方を変更するとします。
変更後、チェックボックスを一括でクリアしたいといった感じです。
やり方に少し特徴があるので、今回はその方法を説明します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/89535b92-4b6a-f82a-0157-5103a84ee2e0.png)

# 実装方法

方法を知ってしまえばかなり簡単なのですが、以下のように、ギャラリー内のチェックボックスの `[Reset]` プロパティを以下のように変数にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/77d66ca2-3dc3-59ea-07f3-95fef40cf496.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/2ea0c659-b3fe-32aa-453a-f16e30a003dc.png)

そして、以下のように、何らかの処理をしたあとに、変数を一度 true にして、false にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/8967fedf-9010-8f9c-870a-40d47de52adb.png)


```
UpdateContext({locResetCheckbox: true});
UpdateContext({locResetCheckbox: false});
```

こうすることで、処理が終わった後、ギャラリー内のチェックボックスのチェックがすべて外れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/0988992e-71b6-f153-3c5c-6e0199348170.png)
Power Apps で Dataverse の選択肢列の既定値を設定する

 
# はじめに

Power Apps でアプリを作る際のデータソースとして SharePoint リストに慣れていると、Dataverse を利用した際、少し混乱することがあります。
今回は、 Dataverse を利用した際に躓いてしまわないよう、Power Apps で Dataverse の選択肢列の既定値を設定する方法を紹介します

# 実装方法

まず、以下のように、Dataverse で選択肢列を作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/02554ba0-b28c-fff6-1722-200b6adf5523.png)

上記選択肢列を利用するフォームを Power Apps で用意します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/b4193c7a-362c-ec79-1984-6d5341247273.png)

`[DefaultSelectedItems]` プロパティを以下のように設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/b353711c-f724-54ef-5392-60e45c05fff6.png)

```
{Value:予定.出社}
```
選択肢名.Value とするのがポイントです。
私が確認する限り、以下のようにテキストで指定した場合、Power Apps 上は一見データが入っているように見えますが、このままフォームを送信しても、Dataverse 側には値は正しく入っていないので注意が必要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/6a3d2bdd-a3ba-1e49-e3d8-770d2be279e1.png)
ZString を使うとむしろ処理が遅くなる

というシチュエーションのメモ。

- `ZString` [Cysharp/ZString: Zero Allocation StringBuilder for .NET Core and Unity.](https://github.com/Cysharp/ZString)

`StringBuilder` なら掛かっても２～３秒で終わる処理が、`ZString` だと１分ほどかかる状態に。


![](https://dl.dropbox.com/s/5n9c3xzv8t2n6i0/ZString%E3%82%92%E4%BD%BF%E3%81%86%E3%81%A8%E3%82%80%E3%81%97%E3%82%8D%E5%87%A6%E7%90%86%E3%81%8C%E9%81%85%E3%81%8F%E3%81%AA%E3%82%8B.png)



# 生成したデータ

- 約15MB、380,000行前後のテキストデータ
- 50文字（アルファベットUTF8、50bytes?）以下の細かい `Append` が大半。
- 各 Append 処理の実行間隔は一瞬。
- `Utf8ValueStringBuilder` / `Utf16ValueStringBuilder` を使っている。
- ファイルの内容的にディスクに直で書き出せば？？ て感じだが、
   - 単体でファイルを書き出すこともあれば、
   - 複数ファイルをまとめたアーカイブのみを書き出したい（一時ファイルは作りたくない）
   - なので一旦メモリに。

※インスタンスが多くてもそれぞれが軽いデータ量だと `StringBuilder` と同等の処理速度が出る。



# 環境

- Unity `2021.3`
- ZString `2.5.0`
   - `System.Runtime.CompilerServices.Unsafe.dll` は他との兼ね合いで `ZString` リポジトリのものとは別のバージョンを使用。（多分 .NET Framework 4.6 系）
   - リポジトリの `Unsafe.dll`（.NET 6 系？）を使ったところで変わらず。
- エディター。
- ビルドはしてない。



# 処理内容

- `ref` で `Utf8ValueStringBuilder` を引き回してる。

- `IDisposable` クラスのコンストラクタで `CreateUtf8StringBuilder` して、後にクラスの `Dispose` 内で `Dispose`。クラスは `using` 。

- ファイルの行数の２倍～程度の回数の `Append` （80万回程度？）
- 文字列連結やフォーマットはほぼしていない。
   - `static void AppendWrapper(ref sb, params object[])` => `foreach...switch { case byte[] ba:...; case bool b:...; case etc:...; }` て感じ。
- 極々々々一部で1MB～程度のバイト列を一気に書き込む。
   - 64KiB毎に分けて `Append` してみたりもした ← 変わらず。
      - 64k??? 👇
      - > `CreateStringBuilder` and `CreateUtf8StringBuilder` must use with `using`. Because their builder rent 64K buffer from `ArrayPool`. If not return buffer, allocate 64K buffer when string builder is created.



---


[速度比較のグラフ](https://github.com/Cysharp/ZString#readme)も `simple string + int concatenation` だし、64KB 以下のテキスト、`"MOJI" + "RETSU" + 10` や `string.Format(...)` の置き換えがメインのライブラリでしょう。`Utf8ValueStringBuilder` はおまけ。多分ね。


GCの負担が無視できないデバイス向けアプリで、ログ出力・UI向け文字列操作が大量にある場合や `using var sb = Utf8ValueStringBuilder` で見える範囲で収まる利用ではない場合には気を付けたい。


--


以上です。お疲れ様でした。
Rubyでの終了判定処理

paiza様の問題集の課題から記事にします。


>2 以上の整数N, Kが与えられます。
>「Nを 2 倍した数でNを更新する」という操作を何度か繰り返すことを考えます。
>このとき, ちょうどある回数 M で N の値は K 以上になります。この時点で操作の繰り返しを終>了することにします。ただし100回を超えることはできません。

Rubyで書いたコードです

```Ruby
    #標準入力
    input_line = gets
    #文字列を「 」で区切って配列に格納する
    array1 = input_line.split(' ')
    #与えられた数
    n = array1[0].to_i
    #超えてはいけない数
    k = array1[1].to_i
    #回数
    s = 0
    #最大計算できる回数
    c = 100
    #ループ処理
    for i in 1..c
        #NがK以上になったらループを抜ける
        if n >= k then
            break
        else
            n *= 2
        end
        # iを変数sに格納する
        s = i
    end    
#結果を表示    
puts s
```

ループ文にして条件を満たしたらループを抜けるようにします。
Yoast SEO OGP画像をカスタムフィールド値で上書き

## YoastSEOではOGP画像にアイキャッチ画像が出力される

YoastSEOでは、記事ページはアイキャッチ画像が出力される仕様になっています。

## YoastSEOでOGP画像を上書きする

今回は、OGP画像をアイキャッチではなく、カスタムフィールドで出力する必要がありました。

`functions.php`に以下の記述をすることで、指定したページに、カスタムフィールドでOGP画像を上書きできます。

``` php
function custom_opengraph_image($img) {
	global $post;

    // Advanced Custom Fields ので設定した`sample_img`の値を取得
	$top_image = get_field('sample_img', $post->ID);

    // 投稿タイプ`sample`の詳細ページを指定
	if (is_singular(array('sample'))){
		return $top_image;
	}
	return $img;
}
add_filter('wpseo_opengraph_image', 'custom_opengraph_image');
```
Build a simple flow trailhead

[Trailhead関係　個別の課題別](https://qiita.com/Keiji_otsubo/items/56eb7a90bb72138ece1f)

# update_toggle

+ [Branch the Flow Challenge - Data type of resource isn't compatible](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000JgArr)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/0bb0db51-df31-5f7d-30e7-9a82b5e809ca.png)

:::note
I had the same exact problem. The update_toggle variable should not be manually assigned. The previous trailhead section needs to be corrected so we configure this correctly.

To edit it in the flows, click on the Contact Info screen, Edit Element. Select the Update_Toggle section that you added, in the menu at the right, open advanced, and then uncheck the box next to Manually Assign Variables. Click Done.

I solved it you have to uncheck Manually assign variables (advanced) in the toggle that you have created

https://salesforce.stackexchange.com/questions/288746/unable-to-get-resource-in-flows
:::

# in the "Branch the Flow Unit" it says {!update_toggle.value} isn't a valid merge field. 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/65d98fe8-e07e-b966-4eab-115b99e3e8c6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/b25cf05d-94e6-f719-f5c4-c42bd21f9829.png)


:::note
I solved it you have to uncheck Manually assign variables (advanced) in the toggle that you have created

https://salesforce.stackexchange.com/questions/288746/unable-to-get-resource-in-flows
:::

# The "Account" screen component isn't properly configured. Check the instructions.

+ [Build A Simple Flow trailhead error](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000Jg12k)

:::note
The problem might be because the screen components have different names.
Also, if you have an old version of Flow, delete it.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/9bd53869-e56b-32b8-bf87-0166ae5accb5.png)
:::

# リソースでオプションが見つかりません この連絡先が既に存在する場合は、既存のレコードと別の条件オプションも更新します。 

+ [Build a Simple Flow > Branch the Flow topic i cant able to find options in resource If this contact already exists, update the existing record and another condition options too . I am attached the screenshot here . help me to complete this trail](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007eplPQ)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/20296b16-0c0c-06a4-b8ad-dc5c274a07fc.png)


:::note
please make sure you typed in well the information / choose the requested component for update_toggle component. That is the one to look for in your decision conditions :
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/4cd780ea-5dc6-182f-a078-ee5e8c41939f.png)


情報を正しく入力し、update_toggle コンポーネントに要求されたコンポーネントを選択してください。それが決定条件で探すものです:
:::
ナルシシスト数を求める

### ナルシシスト数とは

[ウィキペディア](https://ja.wikipedia.org/wiki/%E3%83%8A%E3%83%AB%E3%82%B7%E3%82%B7%E3%82%B9%E3%83%88%E6%95%B0)によれば以下のような数をナルシシスト数と呼ぶそうです。

> n 桁の自然数であって、その各桁の数の n 乗の和が、元の自然数に等しくなるような数をいう。例えば、$1^3 + 5^3 + 3^3 = 153$ であるから、153 はナルシシスト数である。

[Narcissistic Number(Wolfram Mathworld)](https://mathworld.wolfram.com/NarcissisticNumber.html)により詳しい説明と実際の数の列挙があります。ナルシシスト数は有限で理論上60桁以下しかないそうですが、実際の最大値は39桁までの88個だそうです。

### ナルシシスト数を求める

ナルシシスト数を求めるコードは[A005188](https://oeis.org/A005188)のPythonのコードを参考にして書きました。

このコードのポイントは各桁の数の n 乗の和は順序に関係がないので「重複あり組み合わせ」のcombinations_with_replacementを使って計算した結果の数を、桁ごとにばらしてソートしたものが元の組み合わせと同じになるかという判断で行っています。
結果の表示ではナルシシスト数と元の組み合わせのタプルを表示しています。

```python 
from itertools import combinations_with_replacement
N = 10
for k in range(2,N+1):
  pdl = [d**k for d in range(9+1)]  # store d**k of 0..9
  for cd in combinations_with_replacement(range(10), k):
    pds = sum([pdl[pd] for pd in cd])
    if tuple(int(d) for d in sorted(str(pds))) == cd:
      print(k, pds, cd)
#3 370 (0, 3, 7)
#3 407 (0, 4, 7)
#3 153 (1, 3, 5)
#3 371 (1, 3, 7)
#4 8208 (0, 2, 8, 8)
#4 1634 (1, 3, 4, 6)
#4 9474 (4, 4, 7, 9)
#5 93084 (0, 3, 4, 8, 9)
#5 92727 (2, 2, 7, 7, 9)
#5 54748 (4, 4, 5, 7, 8)
#6 548834 (3, 4, 4, 5, 8, 8)
#7 9800817 (0, 0, 1, 7, 8, 8, 9)
#7 4210818 (0, 1, 1, 2, 4, 8, 8)
#7 1741725 (1, 1, 2, 4, 5, 7, 7)
#7 9926315 (1, 2, 3, 5, 6, 9, 9)
#8 24678050 (0, 0, 2, 4, 5, 6, 7, 8)
#8 24678051 (0, 1, 2, 4, 5, 6, 7, 8)
#8 88593477 (3, 4, 5, 7, 7, 8, 8, 9)
#9 146511208 (0, 1, 1, 1, 2, 4, 5, 6, 8)
#9 912985153 (1, 1, 2, 3, 5, 5, 8, 9, 9)
#9 472335975 (2, 3, 3, 4, 5, 5, 7, 7, 9)
#9 534494836 (3, 3, 4, 4, 4, 5, 6, 8, 9)
#10 4679307774 (0, 3, 4, 4, 6, 7, 7, 7, 7, 9)
```

### n進数のナルシシスト数

ナルシシスト数はn進数でも考えることが出来ます。例えば3進数で"12"は$1^2+2^2=5=12_3$となりナルシシスト数です。[Narcissistic Number(Wolfram Mathworld)](https://mathworld.wolfram.com/NarcissisticNumber.html)でも9進数までがリストされています。

Pythonでもnumpyのbase_reprとint関数のbase指定をすると簡単にn進数（36進数まで）を扱うことが出来るので。上のプログラムを少し変えただけでn進数のナルシシスト数を求めることが出来ました。

```python 
from itertools import combinations_with_replacement
import numpy as np
for D in [3,12,16,19,24,30,36]:  #Base 
  nar = []
  for k in range(2,5+1):
    pdl = [d**k for d in range(D+1)]  # store d**k of d=0..D
    for cd in combinations_with_replacement(range(D+1), k):
      pds = sum([pdl[pd] for pd in cd])
      if tuple(int(d,D) for d in sorted(np.base_repr(pds, D))) == cd:
        #print(k, pds, np.base_repr(pds, D), cd)
        nar.append(np.base_repr(pds, D))
  print(f"D={D}: {nar[:11]}")
#D=3: ['12', '22', '122']
#D=12: ['25', 'A5', 'A83', '577', '668', '14765', '938A4']
#D=16: ['208', '5B0', '60B', '8C0', 'EA0', '173', '156', '5B1', '8C1', 'EA1', '248']
#D=19: ['9A', 'AA', '180', '6D0', '70D', '181', '6D1', '278', '58B', 'G8B', 'FDD3']
#D=24: ['J5G']
#D=30: ['28', 'S8', 'JBL', 'GEK', 'B4N9']
#D=36: ['8M0', 'GQ0', '8M1', 'GQ1', '48H', 'N7Q', 'L9Q', 'T40LU', '2L1C6', '6D1MM', '1HDBE']

```

このアルゴリズムはProject Euler, Problem 749: Near Power Sumsを解くのに役に立ちます。

（開発環境：Google Colab）
WordPressのスライドショープラグインSmartSliderで一度設定した画像が表示されなくなる問題。

今回webサイトの作成をしていてトップページにスライドショーを作りたいなと思って調べてたら
「Smart Slider３」というプラグインが良いということで使ってみたんですが、
ちょっとだけ問題があったのでメモしておきます。　　

[smartslider3 プラグイン](https://ja.wordpress.org/plugins/smart-slider-3/)
SmartSlider３の設定方法などはいろんな方が書いてくれてますのでそちらを参考にどうぞ！
[mart Slider 3の使い方](https://webst8.com/blog/wordpress-smart-slider/)

## ちょっと時間が経つと画像が表示されなくなった。
一度設定も済んで画像も表示されてスライドもしたのでよかったなと思っていたら、
リロードすると画像が表示されなくなってしまいました。
![スクリーンショット 2022-12-28 9.34.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2514830/1d871df6-3b6f-8f7d-d31f-3ff46317aba4.png)


コンソールをみると
![MicrosoftTeams-image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2514830/68209350-d91f-14e8-4f6b-72dc37f8bf5f.png)
`The source image cannot be decoded`
「ソースの画像をデコードできません」とのこと・
画像のサイズが設定よりも大きいとこのエラーになるとか書いてあるサイトもあったので試したんですけど解決せず。
smartslider３を再保存すると表示できて、ちょっと経つと表示されなくなるの繰り返しでした。

![MicrosoftTeams-image (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2514830/b0f38059-c0c2-4f7e-ef9c-be53fdee2562.png)
良くみたらパスのファイル名が化けているので日本語ファイル名がダメなのかとおもい変えてみたんですがこれも解決せず。。

## 画像のパスが省略表示なっていたのが原因だった。

先ほどのエラーをよく見るとwordpressのインストールしているサーバーのIPアドレスがパスになっていて
ちょっとおかしいなと思っていたらsmartsliderの画像のパス設定が省略表示（？）相対パス（？）になっていてこれをドメインのパスに直したら表示されるようになりました。
![スクリーンショット 2023-01-12 7.39.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2514830/4de7e639-b1d6-3c7d-2cc7-c13f81d746b8.png)
![スクリーンショット 2023-01-12 7.50.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2514830/94db4350-336d-87fc-636c-1ff9b3cc4952.png)
これでいまのところ問題なく動いています。
なにか他の設定の間違いでこういう現象が起こってたのかもしれませんが。
ハードコーディングについて

# 初めに
研究でハードコーディングを行うとよくないと感じたので書いてみたいと思います！
# ハードコーディングとは
- ハードコーディングとはプログラミングのソースコードを書く際に固定すべきでない値を固定してしまうことです.

例えば以下のようなソースコードを見てみてください！ちなみにこれは死活監視をpythonで実行するコードです．
```python
import subprocess #subprocessをインポート
subprocess.run(["ping","192.168.100.143"]) #死活監視を実行
```
これを見て思うことがありませんか？そう，2行目のIPアドレスの値が固定されています．IPアドレスは, 死活監視を行う上で必須なのですが監視対象が変わった時にいちいちソースコード内のIPアドレスを変更しないといけません.
# 問題点
ハードコーディングの問題点は大きく分けると2つあります．
(1)ソースコードの値が変更になった際にソースコードを記載しているファイルを編集する必要があります．もう一度先ほどのソースコードを見てみましょう！例えばIPアドレスの値を192.168.100.143から192.168.100.1にします．
```python
import subprocess #subprocessをインポート
subprocess.run(["ping","192.168.100.1"]) #死活監視を実行
```
死活監視を行うが変わるたびにIPアドレスをいちいちソースコードを変えるのはめんどくさそうですね．しかもたくさんのソースコードがハードコーディングされているとその分だけコードの変更が必要になるので手間です．

(2)セキュリティー上の問題
ハードコーディングにはセキュリティー上の問題もあります．例えばパスワードや鍵の情報がそのまま直書きされていると，「鍵はここです！」と言っているようなものです．そのため第３者に見られるとまずいソースコードをハードコーディングすると攻撃を受けてしまうかもしれません．

# 終わりに
ハードコーディングを避けて, 効率よくセキュリティーに強いソースコードの記述を心がけていきましょう！
# 参考文献
- https://qiita.com/tetoralynx/items/5238d3a477f8fb9d2574
- https://books.google.co.jp/books?id=K0qWBUOAf6IC&pg=PA188&redir_esc=y#v=onepage&q&f=false
【JavaScript・TypeScript】export default

# export default とは
``.js``ファイルからあるコンポーネントをexportするとき、**export default コンポーネント**とすることで、他のファイルでそのコンポーネントをimportするときに任意の名前で使うことができる、というものです。例を示します。
# 使用例
``Discord.js``でDiscordのボットを開発しているときの例。TypeScript要素ありますが内容わからなくても大丈夫です。
messageCreateというeventと、``!shutdown``で動作を停止する関数handlerを**export default**でexportしています。
```typescript: shutdown.ts
import { Message } from "discord.js";
const prefix = require('../config/config.json').prefix;

const event = 'messageCreate';

const handler = async(message: Message) => {
  if(message.content === `${prefix}shutdown`){
    await message.channel.send("Goodbye!");
    await console.log("shutdown...");
    await process.exit();
  }
}

//ここに注目
export default {event,handler};
```
これを他のファイルでimportするときに、名前を好きなようにつけることができます。``index.ts``というファイルで読み込むとして、
```typescript
import shutDown from "./shutdown";
```
でも
```typescript
import aaa from "./shutdown";
```
でも問題なくimportできるのです。ファイル内で固有のコンポーネント名を持つことができるので便利だという話ですね。

# 配列的なexportなども可
例えば複数機能を持つボットを開発している時。各機能ごとにファイルで小分けして開発することになると思います。
その時、ある``.ts``ファイルで一度すべてのファイルのコンポーネントを集合させて、まとめて実行ファイルにexportすると分かりやすくなります。
```typescript
// コマンドのファイルをインポート
import timeNotificaiton from "./time";
import shutDown from "./shutdown";

// まとめてエクスポート
export default [
  timeNotificaiton,shutDown,
]
```
# 1つのファイル内には一行のみ
**export default**を1つのファイルに複数行書くとエラーになります。勝手に配列に統合するといった機能はないので注意が必要です。
```typescript
// コマンドのファイルをインポート
import timeNotificaiton from "./time";
import shutDown from "./shutdown";

// エラー
export default timeNotification;
export default shutDown;
```
今回は以上です。
wslでelixir その17

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
練習問題やってみた。

# 練習問題
shell serverで、エラーが出たら、プロセスを落とせ。

# 方針

tryで、exitする。

# サンプルコード

```
defmodule Rserver do
  @moduledoc """
  Documentation for `Rserver`.
  """

  @doc """
  Hello world.

  ## Examples

      iex> Rserver.hello()
      :world

  """
  def hello do
    :world
  end
	require Logger
	use GenServer
	@port 5300
	def start do
		GenServer.start(__MODULE__, %{socket: nil})
	end
	def init(state) do
		{:ok, socket} = :gen_tcp.listen(@port, [:binary, active: true])
		send(self(), :accept)
		Logger.info "Listenn port: #{@port}"
		{:ok, %{state | socket: socket}}
	end
	def handle_info(:accept, %{socket: socket} = state) do
		{:ok, _} = :gen_tcp.accept(socket)
		Logger.info "Connected:"
		{:noreply, state}
	end
	def handle_info({:tcp, socket, data}, state) do
		Logger.info "Received: #{String.length(data)}"
		Logger.info data
		Logger.info "Send:"
		try do
			{result, 0} = System.shell(data)
			:ok = :gen_tcp.send(socket, result)
			:gen_tcp.close(socket)
		rescue
			e in KeyError -> 
				Logger.info "Err0:"
			e in RuntimeError -> 
				Logger.info "Err1:"
			e in MatchError -> 
				Logger.info "Err2:"
				exit("stop!!")
		end
		send(self(), :accept)
		{:noreply, state}
	end
	def handle_info({:tcp_closed, _}, state) do
		Logger.info "Close"
		{:stop, :normal, state}
	end
	def handle_info({:tcp_error, _}, state) do
		Logger.info "Error"
		{:stop, :normal, state}
	end
	def run() do
		cmd = IO.gets "> "
		{:ok, socket} = :gen_tcp.connect('localhost', 5300, [:binary, active: false])
		:ok = :gen_tcp.send(socket, cmd)
		{:ok, data} = :gen_tcp.recv(socket, 0)
		data
		|> IO.puts
		run()
	end
	def main(args \\ "") do
		Rserver.start
		run()
	end
	def start(_type, _args) do
		main()
	end
end








```

# 実行結果

```
> Rserver.main
>
07:01:37.521 [info]  Listenn port: 5300

07:01:48.279 [info]  Connected:

07:01:50.813 [info]  Received: 1

07:01:50.813 [info]  l

07:01:50.814 [info]  Send:
sh: 1: l: not found

07:01:50.870 [info]  Err2:

07:01:50.877 [error] GenServer #PID<0.170.0> terminating
** (stop) "stop!!"
    (rserver 0.1.0) lib/rserver.ex:50: Rserver.handle_info/2
    (stdlib 4.0.1) gen_server.erl:1120: :gen_server.try_dispatch/4
    (stdlib 4.0.1) gen_server.erl:1197: :gen_server.handle_msg/6
    (stdlib 4.0.1) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
Last message: {:tcp, #Port<0.7>, "l"}
State: %{socket: #Port<0.6>}

```
以上。
未経験からエンジニアになる！メイン名とIPアドレスを知ろう！

未経験からエンジニアになりたい人は、プログラミングから始める人が多いと思いますが、
エンジニアの仕事は、プログラミングだけではありません。そして、プログラミングだけでは、エンジニアになれません。同時にプログラミングが苦手でも、システム構成や開発の流れを理解するとエンジニアに近づきます！
今回はドメイン名とIPアドレスについてです

![インスタスライド_202301015.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/1b0e74b4-278d-6043-7c0b-34246025b32c.gif)

# ドメイン名とIPアドレス
ドメイン名とIPアドレスは、インターネットで通信するための名前と数値です。
これは、相互に変換する事が出来ます。
どういう仕組みでしょうか？
やってみましょう！

# ネットで調べる
https://www.cman.jp/network/support/ip.html
にアクセス
”IPアドレス検索“で検索しても良いです。

# ”IPアドレス検索“で検索
googleにて”IPアドレス検索“で検索
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/a9f1815a-6d3d-a65a-0c4e-609e14e593f8.png)

# サーチサイトを見る
ドメイン/IPアドレス サーチ　サイト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/8f8e0faa-7bd6-ac41-543f-b32dd18a3bf0.png)

# 実際にやってみる
Googleで照会実行してみましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/d74cc376-8356-17ce-28ca-1db883f314a7.png)

# 照会結果
結果が表示されます。ブラウザからIPアドレスでもアクセスできます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/38761e24-e15b-916e-15a4-68033d574a56.png)

# まとめ
ドメイン名とIPアドレスの検索は簡単にできます。
いつも使っているサイトのIPアドレスを調べてみましょう。
IPアドレスでもサイトにアクセスする事はできます。ブラウザのURLとして入力してみましょう！

# 最後に
未経験の皆さん、若手エンジニアの皆さん、勉強方法について悩みがあればなんでも気軽に質問して下さい！
これからも記事を書いていきますので、モチベーションアップのためフォロー、イイねお願いします。
paiza.ioでelixir その160

# 概要
paiza.ioでelixirやってみた。
tryやってみた。

# サンプルコード

```
try do
	raise "Oh no!"
rescue
	e in RuntimeError -> 
	    IO.puts("An error occurred: " <> e.message)
end
|> IO.inspect

try do
	raise "Oh no!"
rescue
	e in RuntimeError -> 
	    IO.puts("An error occurred: " <> e.message)
after
	IO.puts "The end!"
end
|> IO.inspect

try do
	for x <- 0..10 do
		if x == 5, do: throw(x)
		IO.puts(x)
	end
catch
	x -> 
	    "Caught: #{x}"
end
|> IO.inspect

try do
	exit "oh no!"
catch
	:exit, _ -> 
		"exit blocked"
end
|> IO.inspect


```

# 実行結果

```
An error occurred: Oh no!
:ok
An error occurred: Oh no!
The end!
:ok
0
1
2
3
4
"Caught: 5"
"exit blocked"

```

# 成果物

https://paiza.io/projects/3t5D4ZqJ88lxBqMxSqKjkQ

以上。
Unreal Engine マテリアル更新のボトルネック

# はじめに
備忘録のようなものは需要がないと思いますが, 少しの価値はありそうなので.
Epic Gamesに直接要望だせばと思われるかもしれませんが, 明らかな不具合でない限り改善されるかどうか不確かですし, そもそも直るとも思えないので改造してしまった方が早いでしょう.

# マテリアルのパラメータ更新
UEのマテリアルはランタイムではイミュータブルになります. これを更新可能にするには, マテリアルから`UMaterialInstanceDynamic`を作成します. `UMaterialInstanceDynamic`がパラメータを上書きするプロキシになるわけです.

この`UMaterialInstanceDynamic`を通してパラメータ更新をするとき, 現在のパラメータ値と異なる値で更新しようとしたとき, 最後は`MaterialInstanceSupport.h`の`FMaterialInstanceResource::RenderThread_FindParameterByNameInternal`に到達します.
ここが`5.03`以降のボトルネックになります.

## 5.03
問題はなさそうとはいえ, なんで`int`使ってんだなどのツッコミどころはいろいろありますが, なんとなくカッコイイアルゴリズムのように見えます.

```cpp
template <typename ValueType>
int RenderThread_FindParameterByNameInternal(const FHashedMaterialParameterInfo& ParameterInfo, bool& OutWasFound) const
{
    const TArray<TNamedParameter<ValueType> >& ValueArray = GetValueArray<ValueType>();

    TNamedParameter<ValueType> SearchParam;
    SearchParam.Info = ParameterInfo;

    int Index = Algo::LowerBound(ValueArray, SearchParam,
            [](const TNamedParameter<ValueType>& Left, const TNamedParameter<ValueType>& Right)
            {
            return GetTypeHash(Left.Info) < GetTypeHash(Right.Info);
            });

    uint32 SearchHash = GetTypeHash(ParameterInfo);

    while (ValueArray.IsValidIndex(Index) && GetTypeHash(ValueArray[Index].Info) == SearchHash)
    {
        if (ValueArray[Index].Info == ParameterInfo)
        {
            OutWasFound = true;
            return Index;
        }

        Index++;
    }
    OutWasFound = false;
    return Index;
}
```

問題なのは`GetTypeHash`で, `FHashedMaterialParameterInfo`のハッシュ計算には, `GetTypeHash(FName)`と`HashCombine(uint32,uint32)`が２回必要です. `GetTypeHash(FName)`は, 加算４回＋シフト３回, `HashCombine(uint32,uint32)`は, 加算１回＋減算１８回＋排他論理和９回＋シフト９回です.

`GetTypeHash(FHashedMaterialParameterInfo)`は, **加算６回＋減算３６回＋排他論理和１８回＋シフト２１回**になります.

ハッシュ値計算やデータ構造の複雑さからくるオーバーヘッドの実験はこちら, STLでFNVを使用している場合やはりハッシュ値計算は遅いです.
[小さいサイズの辞書は線形探索でいいかも](https://qiita.com/Nabetani/items/fb19a1c2ac51ad1f9965)

## 4.XX以前
更新されるパラメータが数百個に及ばない限り, 何もする必要がなかったのです. 線形探索しているだけなので遅いように見えますが, `FHashedMaterialParameterInfo`の比較は**高々整数の比較４回**なので, 多くの環境でハッシュ値を計算している間に数十個の要素を比較できることでしょう.

```cpp
TArray<TNamedParameter<ValueType> >& ValueArray = GetValueArray<ValueType>();
const int32 ParameterCount = ValueArray.Num();
for (int32 ParameterIndex = 0; ParameterIndex < ParameterCount; ++ParameterIndex)
{
    TNamedParameter<ValueType>& Parameter = ValueArray[ParameterIndex];
    if (Parameter.Info == ParameterInfo)
    {
        Parameter.Value = Value;
        return;
    }
}
```

## 5.1以降
やはりまずいと思ったのか, 大改造されました. `TMap`ではなく, ここだけの専用のハッシュマップとハッシュ関数に変わりました. 計測はしていませんが, 数十のパラメータ更新ならまだ線形探索の方が速いでしょう.

# まとめ
ハッシュマップからの検索には, ハッシュ値の計算が最低でも１回必要ということが知られていないと思います. 線形探索した方が速いことはよくあります.
ESP32でソケット通信をする(補足)

<h1>はじめに</h1>
<p>ESP32のソケット通信の実装で個人的に理解に苦しんだ部分があったので，補足説明を．参考記事の方と一緒に読んでください．<br>
参考記事：
<a href="https://qiita.com/sirius1000/items/002df5f062a90ed605f0">ESP32でソケット通信をしてみる(Micropython)</a></p>

<h1>ソケット通信，何するの?</h1>
<p>
ソケット通信の細かい仕組みの話は難しいので置いといて，どんなことをしているのかざっくりと説明します．<br>
まず，クライアント側は以下のことを行います．<br>

- ソケット作成
- bind
- connect
- send
- recv
- close

<br>
次に，サーバ側は以下のことを行います．<br>

- ソケット作成
- bind
- listen
- accept
- recv
- send
- close

<br>
たくさんあります．listen,accept,recv(receive)に至ってはどれも似たようなことしそうですしね．混乱します．
</p>

<h2>ソケット作成</h2>

```python
s = socket.socket()
````
ソケットを新規作成します．

<h2>bind</h2>

```python
s.bind((address, port))
```
ソケットにアドレスをバインド(紐付ける)します．
でもaddressが決まってない時もありますよね．
そんな時は

```python
s.bind(("",port))
```
これでaddressを指定せずにbindすることもできます．
バインド済みのソケットを再バインドすることはできません．

<h2>listen</h2>

```python
s.listen(n)
```

サーバが接続を受け付けられるようにします．
電話で例えると着信拒否していない状態，来ていいですよーって受け入れ状態にしておくことです．
引数のnは任意の整数で同時に受け付けられるデバイスの数を指定します．

<h2>accept</h2>

```python
s.accept()
```
後述するconnect()と対(?)になるものです．
接続を受け入れます．
電話で例えると電話に応答する部分に当たります．着信拒否していたら電話に出ることはできませんから，listen()している必要があります．
また，ソケットにアドレスをbindしている必要があります．
戻り値はconn,addrで，それぞれ接続先とのソケット，アドレスを返します．

<h2>connect</h2>

```python
s.connect(address)
```
引数のaddressで接続先を指定します．接続先がacceptしている必要があります．

<h2>recv</h2>

```pyhon
s.recv(bufsize)
```

データを受信します．
引数のbufsizeで一度に受け取るデータサイズを指定します．
<h2>send / sendall</h2>

```python
s.send()
s.sendall()
```

ソケットにデータを送信します．
<h2>close</h2>

```python
s.close()
```

ソケットの接続を切断します．

<h1>全体の流れ</h1>
全体の流れと対応は大体こんな感じです↓

![socket.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747695/009b638e-bdd3-aebc-4501-36a22a0272f8.png)

<h1>終わりに</h1>
他のサイトや公式ドキュメントで詳しく書かれすぎてわからない時はざっくり全体像を掴みながら勉強して行きましょう．
Docker Swarm環境をRaspberry Pi上に構築してみる

Raspberry PiクラスタにDocker Swarm環境を構築した際の手順備忘録になります。

# そもそもDocker Swarmとは？
Dockerコンテナのオーケストレーションツールです。
同じコンテナオーケストレーションツールには有名どころでKubernetesがありますが、Kubernetesと比べると格段に導入コストは低いと個人的には思っています。

現在のKubernetesのコンテナランタイムはcontainerdがデフォルトになっていますが、Docker SwarmはDockerに備わっている機能のため、Dockerの知識さえあれば使えるのも魅力です。

# 事前条件
ネットワーク構成は、以前Kubernetesクラスタを構築した時と同様の構成にしています。詳しくは[こちら](https://qiita.com/hato52/items/2d22a9a24299b2d0c904#%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E6%A7%8B%E6%88%90)を参照してください。
また、各ノードにdockerはインストール済みとします。

# masterノードの構築
masterノード内で下記コマンドを実行する
```
docker swarm init --advertise-addr <masterノードのIPアドレス>
```

実行例
```
pi@master:~ $ docker swarm init --advertise-addr 192.168.1.111
Swarm initialized: current node (xk7z4cc5fplofxj64y3lrvk0x) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token <トークン> 192.168.1.111:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
```



# workerノードの追加
workerノード内で```docker swarm init```実行時に表示されたコマンドを実行すればOK
```
docker swarm join --token <トークン> 192.168.1.111:2377
```

# 確認
masterノードで下記コマンドを実行する
```
pi@master:~ $ docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
xk7z4cc5fplofxj64y3lrvk0x *   master     Ready     Active         Leader           20.10.17
fzpgf5jfphqbi3sft7d7w4jps     worker1    Ready     Active                          20.10.17
iucxr6uzd8eeosxfxqvynwvrd     worker2    Ready     Active                          20.10.17
```
docker swarm joinを実行したノードが追加されていること、STATUSに問題がないことを確認できればOK

# Swarm環境でサービスを起動する
```docker service```コマンドを実行することでswarm環境上にサービスを起動します。
基本的にはdockerコンテナ立ち上げる時とオプションはあまり変わりません。

```--replicas```オプションで指定した数だけサービスが起動します。
```
docker service create \
    --name my-nginx \
    --mount type=bind,src=/data,dst=/sample_volume \
    --publish 8080:80 \
    --replicas=2 \
    nginx:latest
```
サービスの起動状況は```docker service ls```コマンドで確認できます。