OmniAICreator/Qiita-1.07M huggingface dataset:
Knight Tourで経路も求める

[Knight Tour Problem (Graph – Breadth First Search)](https://www.gohired.in/2017/12/22/knight-tour-problem-graph-breadth-first-search/)をPythonで解いてみた。
これはチェス盤上にて開始から終了位置までのナイトの最短手順数を求めるものであるが、[チェスのナイトが出発地点から目標地点まで移動する時のルートを保存、出力したい。BFS Knight's Tour](https://teratail.com/questions/kkp25nbd6nz4y7)で質問されているように途中の経路も出したい。
基本的な流れとしては過去に通った位置をすべて持ったまま幅優先で探索していけばよい。
幅優先なので最短経路が見つかる。
また、最大キュー数はおおよそ盤面のマス目の総数（8x8）× 駒の移動可能数(8)になるはず。
以下コード。やっぱりPythonは楽だ。

なお、開始、終了で互いに位置が異なる全組み合わせを試してみたが、最大でも7手順で収まる。
```Python
from collections import deque
from itertools import permutations

SIZE = 8 # 盤面サイズ

# 結果出力
def print_ans(ps, f):
    for r in range(SIZE):
        line = ''
        for c in range(SIZE):
            p = (r,c)
            line +=  f'{ps.index(p)+1}' if p in ps else '+'
        f.write(f'{line}\n')


def knight_tour(p_st, p_ed): # 開始、終了位置(行, 列)

    visited = set() # 訪問位置の集合
    q = deque()
    q.append([p_st])
    while q:
        ps_cur = q.popleft() # 現在位置

        # ゴールに到達
        p_cur = ps_cur[-1]
        if p_cur == p_ed:
            return ps_cur

        # 未訪問
        if p_cur not in visited:
            visited.add(p_cur)
            # 次の位置を探索
            for dir in [(-2,-1),(-2,1),(-1,2),(1,2),(2,1),(2,-1),(1,-2),(-1,-2)]:
                p_nex = tuple(map(sum, zip(p_cur,dir)))
                # 盤面内
                if all(v >= 0 and v < SIZE for v in p_nex):
                    q.append(ps_cur + [p_nex])
    return None

with open('ret.txt', 'w') as f:
    cnt = 0
    # 開始、終了の全組み合わせ
    for st, ed in permutations(range(SIZE*SIZE), 2):
        p_st, p_ed = (st//SIZE,st%SIZE), (ed//SIZE,ed%SIZE)
        f.write(f'{p_st}->{p_ed}\n')
        ps = knight_tour(p_st,p_ed)
        if ps:
            cnt = max(len(ps),cnt)
            print_ans(ps, f)
    print(cnt) # 7
```
結果
```PlainText
(0, 0)->(0, 1)
14++++++
++2+++++
3+++++++
++++++++
++++++++
++++++++
++++++++
++++++++
：
(7, 7)->(7, 6)
++++++++
++++++++
++++++++
++++++++
++++++++
++++++2+
++++3+++
++++++41
```
PHP マジックメソッド __invoke()について

## 概要

- PHPのマジックメソッドの一つである`__invoke()`について簡単にまとめてみる。

## マジックメソッド

- マジックメソッドが何たるかについては公式ドキュメントに記載されている。
    - [https://www.php.net/manual/ja/language.oop5.magic.php](https://www.php.net/manual/ja/language.oop5.magic.php)
- ようは「特定の動作をさせたときに実行する関数」みたいな感じっぽい。（違ったらすみません。）

## `__invoke()`

- このマジックメソッドは「インスタンス変数を関数のように呼び出したときに実行される関数」らしい。
- 下記を実行すると`xxx`が出力される。

    ```php
    <?php
    
    // クラス定義
    class Foo
    {
        public function __construct()
        {
        }
    
        public function __invoke(string $str1)
        {
            echo $str1;
        }
    }
    
    // インスタンス化してオブジェクトを$fooに格納
    $foo = new Foo();
    
    // オブジェクトを関数のように呼び出し
    $foo('xxx');
    ```

## `__construct()との違い`

- 「〇〇されたときに実行される関数」という共通点で`__construct()`と似ているように感じた。
- ただ、よく考えてみると全然違うものだった。
    - `__construct()`: クラスをインスタンス化する際に実行される関数
    - `__invoke()`: インスタンス化されたオブジェクトを関数のように呼び出す際に実行される関数

## 参考文献

- [https://www.php.net/manual/ja/language.oop5.magic.php#object.invoke](https://www.php.net/manual/ja/language.oop5.magic.php#object.invoke)
react-beautiful-dndでUnable to find draggable with idが出たときの対処法


## 原因

React 18でReact.StrictModeを使っているため

```index.js
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
```

## 対処法
以下のようにReact.StrictModeを使わないようにする

```index.js
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <>
    <App />
  </>
);
```


## 参考
https://stackoverflow.com/questions/60029734/react-beautiful-dnd-i-get-unable-to-find-draggable-with-id-1
cscの作法 その200

# 概要
cscの作法、調べてみた。
qiitapi叩いて、投稿してみた。

# 参考にしたページ

https://qiita.com/kai_kou/items/663d3f7bbc4da4ccf62d


# サンプルコード

```
using System.Collections;
using System.IO;
using System;
using System.Text;
using System.Net;

namespace app
{
	class test0 {
		static void Main() {
			ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
			WebClient wc = new WebClient();
			string TOKEN = "";
			string json = "{\"body\": \"# テスト\", \"private\": true, \"title\": \"テスト\", \"tags\": [{\"name\": \"hoge\", \"versions\": []}]}";
			wc.Encoding = System.Text.Encoding.UTF8;
			wc.Headers.Add("Authorization", "Bearer " + TOKEN);
			wc.Headers[HttpRequestHeader.ContentType] = "application/json";
			string response = wc.UploadString("https://qiita.com/api/v2/items", "POST", json);
			Console.WriteLine(response);
		}
	}
}
```


以上。
cscの作法 その199

# 概要
cscの作法、調べてみた。
qiitapi叩いて、authenticated_userを取得してみた。

# サンプルコード

```
using System.Collections;
using System.IO;
using System;
using System.Text;
using System.Net;

namespace app
{
	class test0 {
		static void Main() {
			ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
			WebClient wc = new WebClient();
			string TOKEN = "";
			wc.Headers.Add("Authorization", "Bearer " + TOKEN);
			string response = wc.DownloadString("https://qiita.com/api/v2/authenticated_user");
			Console.WriteLine(response);
		}
	}
}
```


以上。
Microsoft Certified: Azure Fundamentals（AZ-900）資格勉強方法

AzureのMicrosoft Certified: Azure Fundamentalsに2022年6月に合格したので、勉強方法を共有します。

# 試験概要
概要まとめとしては以下2つがわかりやすくまとまっている

https://qiita.com/mnanri/items/e55ab63d3d62ca634248

https://rikupapa-shima.hatenablog.com/entry/2019/07/06/150330

# 勉強方法

## Microsoft Learn
公式にて無料で学習できる

https://docs.microsoft.com/ja-jp/learn/certifications/azure-fundamentals/

上記Learnの内容を半日x2回で凝縮したウェビナー
参加すると試験1回分の無料バウチャーがもらえる

https://www.microsoft.com/ja-jp/events/top/training-days/azure?activetab=a1%3aprimaryr4

無料でウェビナー形式の問題集解説

https://info.microsoft.com/JA-HCSAzureHybridInfra-WBNR-FY21-02Feb-11-AZ900PrepSession-SRDEM61308_LP02OnDemandRegistration-ForminBody.html

## 書籍
黒本の方がおすすめ

https://www.amazon.co.jp/%E6%A8%A1%E6%93%AC%E5%95%8F%E9%A1%8C%E4%BB%98%E3%81%8D-Microsoft-Azure-Fundamentals%E6%95%99%E7%A7%91%E6%9B%B8-AZ-900/dp/429501141X

https://www.amazon.co.jp/Microsoft%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-AZ-900-Microsoft-Azure-Fundamentals/dp/481561086X

## 無料問題集
無料問題集も質や量も十分でありおすすめ

https://studyand.work/list-question-azure-az-900

https://yukishi.com/8783

https://simple-was-best.com/az-900

## Udemy
更新頻度および量もあり有料の価値あり

https://www.udemy.com/course/az-900-microsoft-azure-fundamentals4176/

https://www.udemy.com/course/az-900-microsoft-azure-fundamentals/
ReactでWarning: Each child in a list should have a unique "key" prop.の対処法


## 概要
タイトルのWarningが出たので、対処方法を簡単にまとめました。

## 問題のコード
```column.jsx
return (
  <>
    {tasks.map((task, index) => <Task id={task.id} task={task} index={index}/>)}
  </>
);
```

```task.jsx
const task = props => {
  const {id, task, index} = props
  return (
    <>
    </>
  );
}
```

## 警告の内容
```
Warning: Each child in a list should have a unique "key" prop.
```

## 理由
コンポーネントで`key`を指定していないから

## 改善策1
以下のように、key=hogehogeを追加する

```column.jsx
return (
  <>
    {tasks.map((task, index) => <Task key={task.id} id={task.id} task={task} index={index}/>)}
  </>
);
```

併せて受け取り側のコードも修正する
```task.jsx
const task = props => {
  const {key, id, task, index} = props
  return (
    <>
    </>
  );
}
```

すると、以下のように別のWarningが表示される
```
Warning: task: `key` is not a prop. Trying to access it will result in `undefined` being returned.
```

これは以下の記事で解説しているように、keyを指定しても受け取り側ではundefinedになってしまうという内容。

https://qiita.com/memomaruRey/items/fb2efa788db2866c2947

## 改善策2

受け取り側で以下のようにkeyを受け取らないようにする。

```task.jsx
const task = ({id, task, index}) => {  
  return (
    <>
    </>
  );
}
```

これで、Warningが出なくなりました。

## 参考
https://reactjs.org/docs/lists-and-keys.html#keys
docker-composeで.envの設定通りに、Mysqlのユーザが作成されない

## 発生した事象

Laravel sail を使用していたところ、DB接続時に以下のエラーが表示され接続できない事象が発生した。

```bash
SQLSTATE[HY000] [1045] Access denied for user 'sail'@' ~
```
エラー内容を確認すると`sail`ユーザーにアクセス権がないようなので、sailユーザーが存在していることやアクセス権周りを確認する。

## 調査した内容

まず、mysqlコンテナに接続し`sail`ユーザが作成されているか確認する。

```bash
$ mysql -h 127.0.0.1 -u root -P 3306
mysql> use mysql;
mysql> SELECT User, Host FROM mysql.user;
+------------------+-----------+
| User             | Host      |
+------------------+-----------+
| root             | %         |
| healthchecker    | localhost |
| mysql.infoschema | localhost |
| mysql.session    | localhost |
| mysql.sys        | localhost |
| root             | localhost |
+------------------+-----------+
6 rows in set (0.00 sec)
```

ユーザ一覧を確認したところ、`sail`ユーザーが作成されていないことが判明。ということは、mysqlイメージ構築時に正常にユーザ等が作成されていないと判断。

イメージ構築時に関連ありそうな`docker-compose.yml`と、同階層の`.env`ファイルを確認する。

```docker
mysql:
        image: 'mysql/mysql-server:8.0'
        ports:
            - '${FORWARD_DB_PORT:-3306}:3306'
        environment:
            MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
            MYSQL_ROOT_HOST: "%"
            MYSQL_DATABASE: '${DB_DATABASE}'
            MYSQL_USER: '${DB_USERNAME}'
            MYSQL_PASSWORD: '${DB_PASSWORD}'
            MYSQL_ALLOW_EMPTY_PASSWORD: 1
        volumes:
            - 'sail-mysql:/var/lib/mysql'
            - './vendor/laravel/sail/database/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh'
```

```bash
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=sail
DB_PASSWORD=sercret
```

[Docker Mysqlのドキュメント]([https://hub.docker.com/_/mysql](https://hub.docker.com/_/mysql)) より`MYSQL_USER`に設定されているユーザがイメージ開始時に、作成されるはずだが、作成されていない。

docker-composeのconfigを確認しても、環境変数は反映されていて問題なさそう。。

```bash
$ docker-compose config
mysql:
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: 1
      MYSQL_DATABASE: laravel
      MYSQL_PASSWORD: sercret
      MYSQL_ROOT_HOST: '%'
      MYSQL_ROOT_PASSWORD: sercret
      MYSQL_USER: sail
```

## 原因

結論からいうと、DBをVolumuesで永続化しているのが原因でした。

なのでdown時に-vオプションを使用してVolumesを削除し、buildし直すことで事象が解消されました。

```bash
$ docker-compose down -v
$ docker-compose up -d --build
```
## 参考文献
- [Docker ボリュームの利用](https://matsuand.github.io/docs.docker.jp.onthefly/storage/volumes/#remove-volumes)
- [docker-compose down](https://docs.docker.jp/compose/reference/down.html)
- [Laravel sail](https://readouble.com/laravel/8.x/ja/sail.html)
[Micorosoft Graph] DirectoryObject から DisplayName を取得したい

自分が所有者になっているグループの一覧を取得したい。

```cs:Program.cs
using Azure.Identity;
using Microsoft.Graph;

var scopes = new[] { "Directory.Read.All" };

var tenantId = "common";

var clientId = "{ Client_Id }";

var options = new InteractiveBrowserCredentialOptions
{
    TenantId = tenantId,
    ClientId = clientId,
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
    RedirectUri = new Uri("http://localhost:5001/"),
};

var interactiveCredential = new InteractiveBrowserCredential(options);

var graphClient = new GraphServiceClient(interactiveCredential, scopes);
var ownedObjectsPage = await graphClient.Me.OwnedObjects
    .Request()
    .Select("id,displayName")
    .GetAsync();
var ownedObejcts = ownedObjectsPage.Where(g => g.ODataType == "#microsoft.graph.group");

foreach (var obej in ownedObejcts)
{
    Console.WriteLine(obej.DisplayName); // ここでエラー
}

```

しかしこれだと obej に DisplayName がないと言われてしまう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383318/7e5d7620-5837-5dd4-e0ca-bb3e4ba4122a.png)

しかし Graph Explorer では DisplayName もちゃんと取れるし JSON にシリアライズしてみるとちゃんと DisplayName も持っている。

```cs:Program.cs
using System.Text.Json;
using Azure.Identity;
using Microsoft.Graph;

var scopes = new[] { "Directory.Read.All" };

var tenantId = "common";

var clientId = "{ Client_Id }";

var options = new InteractiveBrowserCredentialOptions
{
    TenantId = tenantId,
    ClientId = clientId,
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
    RedirectUri = new Uri("http://localhost:5001/"),
};

var interactiveCredential = new InteractiveBrowserCredential(options);

var graphClient = new GraphServiceClient(interactiveCredential, scopes);
var ownedObjectsPage = await graphClient.Me.OwnedObjects
    .Request()
    .Select("id,displayName")
    .GetAsync();
var ownedObejcts = ownedObjectsPage.Where(g => g.ODataType == "#microsoft.graph.group");

foreach (var obej in ownedObejcts)
{
    var jsonString = JsonSerializer.Serialize(obej);
    Console.WriteLine(jsonString);
}

```

結論、DirectoryObject にはプロパティがないのでキャストしてあげれば OK。

```csharp:Program.cs
using Azure.Identity;
using Microsoft.Graph;

var scopes = new[] { "Directory.Read.All" };

var tenantId = "common";

var clientId = "16b9bba3-76fd-4077-aac1-f03b343321a6";

var options = new InteractiveBrowserCredentialOptions
{
    TenantId = tenantId,
    ClientId = clientId,
    AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
    RedirectUri = new Uri("http://localhost:5001/"),
};

var interactiveCredential = new InteractiveBrowserCredential(options);

var graphClient = new GraphServiceClient(interactiveCredential, scopes);
var ownedObjectsPage = await graphClient.Me.OwnedObjects
    .Request()
    .Select("id,displayName")
    .GetAsync();
var ownedObejcts = ownedObjectsPage.Where(g => g.ODataType == "#microsoft.graph.group");

foreach (var obej in ownedObejcts)
{
    Console.WriteLine(((Group)obej).DisplayName);
}

```
Laravel開発時エラー、やったこと覚えている範囲で・・・

# 学習を進めた時のエラー解除？やってみたこと（自分用メモ）
動画を見ながらLaravel開発環境構築をしていましたけど、なかなかうまくはいきませんでした。
## Laravelを立ち上げるときに発生したエラー
まずはどこに立ち上げたのかわからなくなってしまったけれど、userの直下ディレクトリ内にできたらしい。
そのtodoを引っ張ってきてvscode内に展開、npmもアップデートしないといけないようなエラーが出たけど、なんかよくわからないけど解消されたらしい。
Laravel自体のバージョンは最新のものらしい（todo）の名前で立ち上げたものは・・・
`$ php artisan serve`
このコマンドを打つと、あら不思議！
Localhost:8000番で開発サーバーが立ち上がってくれる！
composer.lockやcomposer.jsonに書いてあるものとバッティングしていてlarval/uiのDLがやりにくかったけれど、version指定を外したら最新のUIが実装できました。

`$ composer require laravel/ui "^1.2"` ←クォーテーション内のものを削除してコマンドを実行
本当はlockとかjson内に書いてあるversionに合わせないと良くない。
あとはどんなエラーが出たか覚えはないけど、次回もこのような感じで、メモを残していきたいと思います。
Azure Public IP の逆引き DNS にカスタムドメインを設定してみた

## 背景と目的

別件の検証中に Azure Public IP のドキュメントを読んでいたら、ふと逆引き DNS にカスタムドメインって設定出来るんだっけ？と気になり、実際にやってみたらカスタムドメインを設定出来ちゃいました。逆引き DNS にカスタムドメインを設定する用途は、昔ならメール送信サーバーからのメールがスパム扱いにならないようにするためでした。Azure でメール送信と言えば SendGrid か Exchange Online を使っていたので、今までこの機能に気が付きませんでした。いつか自分の役に立つ日が来そうな予感がするので、検証結果を残しておきます。

## 検証用のリソースグループを作成

```bash:bash
# 環境変数をセットします
region=japaneast
prefix=mnrexample

# リソースグループを作成します
az group create \
  --name ${prefix}-rg \
  --location $region
```

## 事前に Public IP の CNAME レコードを Azure DNS に作成

```bash:bash
az network dns record-set cname set-record \
  --resource-group common-rg \
  --zone-name example.com \
  --ttl 300 \
  --record-set-name ${prefix} \
  --cname ${prefix}.$region.cloudapp.azure.com
```

## Public IP を 逆引き DNS 付きで作成

```bash:bash
az network public-ip create \
  --resource-group ${prefix}-rg \
  --name ${prefix}-pip \
  --allocation-method Static \
  --sku Standard \
  --dns-name ${prefix} \
  --reverse-fqdn ${prefix}.example.com
```

## Public IP の DNS 設定を確認

```bash:bash
az network public-ip show \
  --resource-group ${prefix}-rg \
  --name ${prefix}-pip \
  --query dnsSettings
{
  "domainNameLabel": "mnrexample",
  "fqdn": "mnrexample.japaneast.cloudapp.azure.com",
  "reverseFqdn": "mnrexample.example.com"
}
```

## Public IP の 逆引きを試す

```bash:bash
pip=$(az network public-ip show \
  --resource-group ${prefix}-rg \
  --name ${prefix}-pip \
  --query ipAddress \
  --output tsv)

host $pip
177.47.89.20.in-addr.arpa domain name pointer mnrexample.example.com.
```

## 参考

```bash:bash
# 検証用のリソースグループを削除します
az group delete \
  --name ${prefix}-rg \
  --yes

# 検証用の CNAME レコードを削除します
az network dns record-set cname delete \
  --resource-group common-rg \
  --zone-name example.com \
  --name ${prefix} \
  --yes
```

https://docs.microsoft.com/ja-jp/azure/dns/dns-reverse-dns-for-azure-services
[Rails][Ruby] update_allとwhereを使用するときに気をつけること

## はじめに
未経験からエンジニアに転職して、２ヶ月ほど経つエンジニアです。
業務にあたりながらも、小規模なアプリを作って楽しんでいます。
今回は大量のレコードをまとめて更新するときに重宝する update_all についてです。

## 結論
update_all を使用するときはクエリの実行タイミングに注意しよう。

## update_all とは
>条件に一致するレコードをSQLを直接実行して全て更新
updated_atとupdated_onは更新されない

バリデーションやトランザクションを無視する点も注意が必要です。

https://railsdoc.com/page/model_update_all

## クエリキャッシュのタイミングに注意
~~~ruby
def update_user_data
 #このタイミングではクエリは走らない
 users = User.where(id: XXX, status: XXX, ...) 

 #上記 where と組み合わせて UPDATE users ... FROM ... WHERE ... が走る
 users.update_all(
   status: XXX,
   updated_at: Time.current
  ) 

 # この時、usersは空になってしまう (SELECT * FROM users WHERE ... が走る)
 # p users = []
 users.each do |i|
  ...
 end
end
~~~

そもそもupdate_allが必要なのか検討してみてください。
update_allを使用したい場合は以下のようにすることで解決できます。
~~~ruby
def update_user_data
 #このタイミングではクエリは走らない
 users = User.where(id: XXX, status: XXX, ...) 
 # users　を保存しておく(ActiveRecord:Relationではない状態にして保存)
 users_before_update_all = users.to_a

 #上記 where と組み合わせて UPDATE users ... FROM ... WHERE ... が走る
 users.update_all(
   status: XXX,
   updated_at: Time.current
  ) 

 # 保存した方を使う
 users_before_update_all.each do |i|
  ...
 end
end
~~~


## まとめ
update_allは
複数のレコードを一括で更新できます。
DBへの負荷を軽減できます。

一方で、下記のような注意するべき点があります。
- バリデーションを実行しない
- トランザクションを実行しない
- 更新前の状態に依存する
- updated_at を自動更新しない

## 参考

https://teratail.com/questions/32603

https://railsdoc.com/page/model_update_all
スクロールのイベントを間引くthrottle


## throttleで負荷軽減

scrollやresizeなど、連続してイベントが呼ばれてしまうため、
カクカクした動きになったりCPUに負荷をかけてしまうことがあります。


負荷軽減のためイベントの呼び出しは指定時間が経過した時や、
イベントの最後にだけ呼ばれるに呼ばれるようにします。


それを実現するものとして、
`指定した時間間隔でイベントを発生させるthrottle`と
`連続したイベントの最後のみ処理するdebounce`があるようですが、今回はthrottleについてみていきます。

## 指定した時間間隔でイベントを発生させるthrottle

### 間引く前

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="gOvEqMW" data-user="sora888" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/sora888/pen/gOvEqMW">
  without throttle</a> by sora (<a href="https://codepen.io/sora888">@sora888</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
まず間引く前(throttle関数を使用しない時)のスクロールはこちら。
ばんばんイベント発生しているのがわかりますね。

### 間引き後　
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="dydaaqz" data-user="sora888" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/sora888/pen/dydaaqz">
  throttle example</a> by sora (<a href="https://codepen.io/sora888">@sora888</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

こっちが間引いた後のスクロール
間引く前と比べてイベント発生が減っているのがわかると思います。
このイベント発生は指定した時間によって調整ができます。





※1フレーム(1/60fps)＝ 1/60秒 = 約16ms

## throttleを自作する

```ts
export const throttle = (fn: () => void, interval: number): (() => void) => {
  let time = Date.now() - interval;
  return () => {
    if (time + interval < Date.now()) {
      time = Date.now();
      fn();
    }
  };
};
```


## ライブラリを使う
[lodashが提供しているthrottle](https://lodash.com/docs/4.17.15#throttle
)が使えます！

` _.throttle(関数, wait時間) `で囲むだけで実現できるので取り入れやすいですね。
Shopifyのページネーションで全プロダクトとタグをGET

# Shopifyページネーションの関数
ShopifyApiライブラリ試したが、ドキュメント少ないし、Webhook登録で挙動がおかしい&Github Issueで指摘されているにも関わらず回答放置（？）のようで、頼らないことにした。
Shopifyのページネーション情報は
- ヘッダーに格納されている
- `<リクエストURL>; rel="next/previous"`という風な文字列になっていて、分解しないといけない
- "次"がない時は同様のヘッダーが存在するが`rel="previous"`になる/最初から"次"がない=１リクエストで完結する時はそのヘッダーがない

という仕様で若干ややこしいので関数化することにした。後でClass化しようかな。

```python
# <SHOP>, <API_VERSION>, <ACCESS_TOKEN>は自分でセットしてね

shop_url = f"{SHOP}.myshopify.com"
api_version = "<API_VERSION>"
baseURL = rf"https://{shop_url}/admin/api/{api_version}/"
headers_ = {'Content-Type': 'application/json',
            'X-Shopify-Access-Token': ACCESS_TOKEN}

def get_productsANDtags():
    import re, requests

    products = []
    next = ""
    rel = "next"
    page_info = ""
    # CAUTION : Archived以外でかつフィールドが絞られています。
    product_params_ = {"status": "active,draft", "limit" : 250, "fields":"id,title,tags,variants"}
    s = re.compile('page_info=(.*?)>.*rel="(.*?)"')

    while next != None and rel != "previous":
        if next != "":
            product_params_["page_info"] = page_info
            product_params_.pop("status", None)
        products_r = requests.get(baseURL + "products.json" , headers= headers_, params=product_params_)
        products.extend(products_r.json()["products"])
        next = products_r.headers.get("link")
        if next != None:
            regexSearch =re.search(s,next).groups()
            page_info = regexSearch[0]
            rel = regexSearch[1]
    tags = [product["tags"].split(",") for product in products]
    tags_flat = set([tag for tag_set in tags for tag in tag_set])
```
# ちなみに①
"全タグ"、ということならサーチテンプレをLiquidで作ってそれをgetする、という方法がこちらに紹介されている↓
https://stackoverflow.com/questions/60920840/get-all-tags-used-by-a-shopify-shop-in-one-request
# ちなみに②
ShopifyApiライブラリで全プロダクトと全タグGETなら
```python
ShopifySession = shopify.Session(shop_url, api_version, ACCESS_TOKEN)
shopify.ShopifyResource.activate_session(ShopifySession)

all_Shopify_products = []

products = shopify.Product().find(limit=250, status = "active,draft",fields="id,title,tags,variants")
# パラメーターをそのまま使える感じ
all_Shopify_products.extend(products)
has_more = products.has_next_page()

while has_more:
     products = products.next_page()
     all_Shopify_products.extend(products)
     has_more = products.has_next_page()

tags = [product.tags.split(",") for product in products]
tags_flat = set([tag.strip().replace("\t","") for tag_set in tags for tag in tag_set])
# タグの中にtabを見かけたことがある

shopify.ShopifyResource.clear_session()

```
C++関数エクスポート（DEFモジュール定義ファイル編）

# 前書き

前は、下記記事でdllexportを中心にDLL関数のエクスポートについてメモしました。
>[dllexportとdllimportの使い方](https://qiita.com/Pirlo/items/e603efddac6712e0bf8e)

>[C++関数のエクスポート（dllexport + extern "C" 編）](https://qiita.com/Pirlo/items/d17f049fde276427a37b)

この記事で、dllexportと異なる方法をメモします。

# モジュール定義（DEF）ファイル
下の図のように、Visual Studioでモジュール定義ファイルをプロジェクトに追加することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188794/3631a08c-817a-962f-c906-20b7d34c7cfc.png)


このファイルに、
[関数名] @[番号]
のように記載すれば、関数がエクスポートされます。
```c:source.def
LIBRARY
EXPORTS
output	@1
```
※「@」の後ろにある番号は、以下の事象と関連しています。
>[「序数 X がダイナミックライブラリから見つかりませんでした」というエラーの原因](https://qiita.com/Pirlo/items/674f1f0b63c9d6764b0d)


DEFファイルが作成されてからコンパイルすれば、DLLと同名のlibファイルが作成され、DLLファイルにエクスポート情報が追記されます。
※確認方法は下記記事のDUMPBINの部分を参考
>[C++関数のエクスポート（dllexport + extern "C" 編）](https://qiita.com/Pirlo/items/d17f049fde276427a37b)

# モジュール定義ファイルのメリット
>[C++関数のエクスポート（dllexport + extern "C" 編）](https://qiita.com/Pirlo/items/d17f049fde276427a37b)

上記記事に記載されている「Hello.h」ファイルと比べて、dllexportやextern "C"などの記載は不要になります。

ファイル数が1個増えましたが、ソースの可読性が向上します。
（特にWindows仕様があまり好きじゃない人に対して）

```c++:Hello.h
#pragma once

#include<stdio.h>

//①defファイルを使うとdllexportは不要
//#ifdef CPPDLL_EXPORTS
//#define DECLSPEC __declspec(dllexport)
//#else
//#define DECLSPEC __declspec(dllimport)
//#endif

typedef struct {
	int id;
	char name[20];
}st_info;

//②defファイルを使うと、extern "C"の指定も不要
//extern "C" {
//	DECLSPEC int output(st_info*);
//}

//③単純に関数を宣言するだけでよい
int output(st_info*);
```
Unityで、スタンドアロン型VR機のゲーム中に2万人を超える観衆をレンダリングする

本記事は、「ソフトウエア研究会in秋葉原」で2021年に発表した、個別にアニメーションをする2万人を超える観衆の3Dモデルをレンダリングする技術の発表資料です。

本技術は、公開済みのQuest向けVRテニスゲーム[CYBER TENNIS](https://cybertennis.jp) で使われています。

<iframe src="https://docs.google.com/presentation/d/e/2PACX-1vTyBRden6R7V7orXSZCDF4ZiWBxF02dwz9JUwVRB6V4MrBPJgyn0w-CJ_lQz0ioHoFsZGEZJ8P_VmPV/embed?start=false&loop=false&delayms=3000" frameborder="0" width="640" height="480" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>

https://drive.google.com/file/d/1CBBBqbQlOVxcqminxlTYDd2NHsae03Au/view?usp=sharing
Arduino UNOのボリュームの入力でPWM出力


目的
教科書的プログラムを書いて遊ぶ
一部教科書から逸脱した毒も込み(2ビット右シフト)


![o_con545.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/00fd510c-9326-58a0-9ece-e9914da2b292.jpeg)


![o_con546.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/2c93790a-c0ef-1b45-ef2f-963dc9c8bb8f.jpeg)



```c++

//PWM_ Potentiometer_UNO_1

#include <Arduino.h>

//初期化処理
void setup()
{

  Serial.begin(9600); //シリアルポートの初期化

} //setup

//メインループ
void loop()
{

  //センサーの値を読み込む
  int sensorValue = analogRead( A0 );

  //センサーのADC値をPWMの値に変換
  int outputValue = map(sensorValue, 0, 1024, 0, 256);

  //Debug
  //int outputValue = sensorValue >> 2;

  //PWMの出力
  analogWrite( 5 , outputValue );

  //PWMの値の表示
  Serial.print("PWM = [");
  Serial.print(outputValue);
  Serial.print("]");
  Serial.println();

  //0.5秒の待ち
  delay(500);

} //loop



```
firebaseの匿名認証を使っていると既に認証したユーザとは違う別のユーザとして認証されてしまう現象の対応法

こんにちは。[virapture株式会社](https://virapture.com)でCEOしながら[ラグナロク株式会社](https://ragna-rock.com)でもCKOとして働いている[もぐめっと](https://mogmet.com)です。

本日はなんでかわからないけどきっと困った人がいるんじゃないかというFirebaseAuthの匿名認証での現象の対応法です。

## 症状

FirebaseAuthの匿名認証はGoogleのエンジニアいわく、基本的に一度認証したら変わることがありません。

https://stackoverflow.com/questions/41733137/firebase-auth-anonymous-login#comment70661655_41733137

> Anonymous authentication tokens do not expire and are persisted to disk between runs of your app.

自分が確認している仕様としては下記になります。
- iOSはKeychainに保存しているらしく、再インストールしても変わりません。
- Androidはアプリを再インストールすると変わります。

しかし、なぜかアプリを起動したら変わってしまうということがありました。
しかもなかなか再現せずに結構苦戦していました。

## 原因

こちらに答えがありました。

https://firebase.google.com/docs/auth/android/manage-users#get_the_currently_signed-in_user

> getCurrentUser が null を返す原因としては、Auth オブジェクトの初期化が完了していないことも考えられます。

https://firebase.google.com/docs/auth/ios/manage-users#get_the_currently_signed-in_user

> 注: Auth オブジェクトの初期化が完了していない場合も、currentUser が nil になることがあります。

なんということでしょう・・・／(^o^)＼
Authの初期化が終わってないと別ユーザとして認識されてしまうみたいでした。

## 対策

先程のURLに対策も書いてあります。

> [AuthStateListener](https://firebase.google.com/docs/reference/android/com/google/firebase/auth/FirebaseAuth.AuthStateListener) をアタッチすると、基になるトークンの状態が変わるたびにコールバックが返されます。これは、上記のようなエッジケースに対応するのに便利です。

ということで、signInAnonymouslyはリスナーを使って状態を判定した上で実施するようにしましょう！

ちなみにリスナーのイベントは下記タイミングでくるみたいです。

> Right after the listener has been registered （リスナー登録直後）
> When a user is signed in （サインイン時）
> When the current user is signed out (サインアウト時)
> When the current user changes (ユーザが変わった時）

## まとめ

匿名認証を使う場合は**リスナーイベント**を必ず使うようにしましょう！

そして、この対策を教えてくれたラグナロクCTOの[@juju](https://twitter.com/piatekju)に感謝を！！！

最後に、[ワンナイト人狼オンライン](https://online.1nite-jinro.com/link/blog)というゲームを作ってます！よかったら遊んでね！

https://online.1nite-jinro.com/link/blog

他にも[Camecon](https://camecon.me/)や[Offcha](https://offcha.com/)、問い合わせ対応が簡単にできる[CSmart](https://csmart.jp/lp)といったサービスも作ってるのでよかったら使ってね！

https://camecon.me/

https://offcha.com/

https://csmart.jp/lp

また、チームビルディングや技術顧問、Firebaseの設計やアドバイスといったお話も受け付けてますので御用の方は弊社までお問い合わせください。

https://virapture.com/

ラグナロクでもエンジニアやデザイナーのメンバーを募集しています！！楽しくぶち上げたい人はぜひお話ししましょう！！

https://ragna-rock.com
Microsoft Teamsの不調時の対処

# はじめに

![Microsoft_Teams_128x128.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/2154c900-cd94-e781-51f2-16caa60ecd53.png)
　「Teamsがうまく起動しない」、時々あります。サポートへの問い合わせをして原因を特定して... が順路です。
しかし、それは時間がかかります。そこで
　**「再インストールすればほぼ確実に正常化する」**  
という経験則に落ち着きました。OS別に書いてみます。すべて最近（2022年6月頃）の経験です。
　こちらの案内は私個人の経験則です。ご参考にしていただき、最終的には利用者の自己責任で対処をお願いします。

## 再インストールの前に試すこと1
 Teamsはアプリを閉じた後、最小化してタスクバーに残っていることがあります。
タスクバーの通知領域から、Teamsアイコンをクリックして終了します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/e44b4825-b4b4-1c05-9ba3-567f9644ade7.png)

白いTの文字があるTeamsは個人用のTeams（家庭/小規模ビジネス向けの Teams）なので別物です。

このことは、Teamsアプリの設定にもありますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/336c88d8-3772-f9c7-cbf1-50154e023705.png)

## 再インストールの前に試すこと2
 それでもPC本体を再起動する。これで直ることも多くあります。

## Windowsでの再インストール
　アプリの起動でに数分待たされ、急いでいるのにいつ起動するのやら..となった場合の対処です。

- [設定]/[アプリ]/[アプリと機能]から[Microsoft Teams]をアンインストール
- 以下よりデスクトップ版をダウンロードしてインストールする。「職場/学校向けの Teams」を選択。

https://www.microsoft.com/ja-jp/microsoft-teams/download-app 

## MacOSでの再インストール

　Teamsが起動するものの、右上から組織プロファイルを切り替えようとすると、切り替え画面が数分変わらない... となりました。

- デスクトップ版をダウンロードしてインストールする。「職場/学校向けの Teams」を選択。

https://www.microsoft.com/ja-jp/microsoft-teams/download-app 

 上書きインストールしました。

## iOSでの再インストール

　数日前まで正常だったのに、ある日以降Teams会議で音声が何やってもでない、となりました。
2台のiPhoneで同様の現象に。

- 一度アンインストール（アイコンを長押しでアプリを削除）
- App Storeから再インストールで難なく正常化

　いろいろ設定をいじったりする時間は不要でした。早く再インストールすればよかったです。

同じiOSにMicrosoft Authenticatorが入っていると、利用中のMicrosoft 365のアカウントに関する認証情報も残っているので、何もかも最初から設定する、という手間なことはありません。

https://www.microsoft.com/ja-jp/security/mobile-authenticator-app

## 有用な参考サイト

- [【Teams】Teams クライアントアプリの動作がおかしいときの対処メモ その１ - ふらりのメモ書き]( https://flali.hatenablog.com/entry/2020/05/08/204045)
- [【Teams】Teams クライアントアプリの動作がおかしいときの対処メモ その2 - ふらりのメモ書き]( https://flali.hatenablog.com/entry/2020/05/09/161948)

# おわりに
　上記のようにわたしの経験上、どのようなOS、MDMの有無も含めて）どのようなネットワーク等の環境下でも、こちらでほぼ対処できています。Teamsで困ったときはご検討ください。
Arduino UNOでセンサーの値を電圧で表示する。(浮動小数点使用)


x いちおう書いておくがあまり「正確」じゃない　ちょつとだいたいね～


目的
例題中例題で教科書的なプログラムを組んで電圧を見て「にぁにぁ」して遊ぶ。
なにが楽しいのかは、秘密。

![o_con543.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/194a5422-c735-c9fd-c6e6-7acc9c2675b6.jpeg)


プログラムサイズ 3,174バイト


![o_con544.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f04cca40-f9f3-0455-5e9b-d9b42706bfee.jpeg)



```c++


//SER_Voltage_float_UNO_1

#include <Arduino.h>

//初期化処理
void setup()
{

  Serial.begin(9600); //シリアルポートの初期化

} //setup

//メインループ
void loop()
{

  //センサーの値を読み込む
  int sensorValue = analogRead(A0); // UNO

  //int s = sensorValue;
  //int s = 82;   //debug
  //int s = 1024; //debug
  //Serial.print("Debug Voltage[");
  //Serial.print( ( (unsigned int)0b100111 * (unsigned int)s + (s >> 4 ) ) >> 3);
  //Serial.println("]");

  //センサーのADC値を電圧に変換
  float Voltage = sensorValue * ( 5.0 / 1024.0 );

  //電圧の表示
  Serial.print("Voltage = [");
  Serial.print(Voltage);
  Serial.print("]");
  Serial.println();

  //0.5秒の待ち
  delay(500);

} //loop


```

3.3V系　Arduino


```c++

  //センサーのADC値を電圧に変換
  float Voltage = sensorValue * ( 3.3 / 1024.0 );


```
はじめてのDelphi LSP

# はじめに
Delphi LSPを触ってみたので、感想をば。

# Delphi LSPとは
私が説明するより以下の記事が詳しい。
[Delphi LSP を Visual Studio Code から使う](https://qiita.com/ht_deko/items/43344648068ee84e3017)

# 使ってみた動機
業務ではDelphi XE5で開発しているわけなんですが、いかんせんエディタが使いづらい(ろくに矩形選択が使えないってどういうことよ...)。仕方ないので普段は適当なテキストエディタ(EmEditor)で開発してるわけですが、なんとVS Codeで開発できるとの記事を発見！さっそく触ってみたわけなのです。

# 所感とか、いろいろ
触る前に考えてた疑問に対する答えとか。

## 当機能はなんのためにある？
公式(エンバカデロ社)の見解は以下です。
>if you prefer our editor, then there's no reason to use VSCode! But some people prefer our editor, and some don't. We want to let those who want edit Delphi some other way do so, so we made the same LSP server engine we use inside Delphi available here for VSCode. The licensing is because this is part of the product, it needs to be installed.
出典:[Rating & Reviews](https://marketplace.visualstudio.com/items?itemName=EmbarcaderoTechnologies.delphilsp&ssr=false#review-details)

要は、「みんなが普段から使い慣れてるVS Codeでも開発できる機能を提供したよ、RAD Studioで満足してるなら使わんでおｋ」っていうことっぽい。
RAD Studioってフリーカーソルで、Visual StudioやVS Codeでの開発に慣れてる人にはどうしても使いづらいと思います。そんな人には向いてるのやもしれません。

## 「no license」が表示される問題
ライセンスがProfessionalやEnterpriseの場合、ろくに使えません。回避方法が分からん...

## Delphi XE5では使えない
当機能が使えるのはDelphi 10.4からです(当たり前ですが)。それ以前のバージョンでは使えません。

## VS Codeでデバッグ・ビルドできる？
できないです。RAD Studioにもどってデバッグ・ビルドします(回避策はあるかもだが...)。

## dfmといってデザイナは開ける？
開けないです。VCLの画面イメージとかが開けないということです。

# 結論：最大のメリット
個人的に考える最大のメリットはLive Shareの機能が使えることです。ざっくりと使ってみましたが、結構使い物になりました。
【TypeScript】Conditional Types

## conditional types
```ts
// type Exclude<T, U> = T extends U ? never : T;
type MyExclude = 
( string extends string | number ? never : string )  // never
| ( number extends string | number ? never : number )  // never
| ( DebugType extends string | number ? never : DebugType )  // DebugType
type MyFunctionType = MyExclude

```

## infer
```ts
type MyReturnType<T extends (...args: any) => any> = T extends (
  ...args: any
) => infer R 
? R 
: any;
// infer = 条件の一部としてジェネリクス型（<T extends (...args: any) => any>）を宣言することができる
// infer R = <T extends (...args: any) => any> 後ろのanyを取得
// (...args: any) => any = 関数を意味する → Tは関数
```
仮想通貨をローソク足でグラフ出力

# Ta-Libraryとは
金融データをテクニカル指標などで分析が行えるツール
https://mrjbq7.github.io/ta-lib/

# 準備
## 必要ライブラリをインストールする
```
!brew install ta-lib
!pip install TA-Lib mplfinance
```
## Binanceから過去データを取得
下記URLを参考に取得
http://algotrade-for-everyone.com/2021/07/14/binance-get-historic-data/


# 出力
使用するライブラリをimportします。
```
import talib
import pandas as pd
import mplfinance as mpf
```

取得したデータをdatetime型に変更して読み込める形にする。
```
df['date'] = pd.to_datetime(df['Time'])
df = df[['Open', 'High', 'Low', 'Close', 'Volume','date']].set_index('date')
```


Mplfinanceの表示できる制限があるため、500まで
```
df.head(500)
```

あとは表示するだけ
```
mpf.plot(df, 
         type='candle',
         style='binance',
        addplot = macd_dataset)
```
AWS Control TowerでKMS暗号設定したらエラーになった

## 事象 
AWS Control Towerでマルチアカウントを試したくてボタンをポチポチ。
KMS暗号を有効化し、流れで新規作成。
そのまま進めていったら、KMS暗号がなんちゃらでエラー。
悲しすぎるぜ。

```
Policy does not allow required actions for required service
```

## 解決方法

ポリシーが足りないらしいです。
下記の記事を参考に、Principal > Serviceの2行（cloudtrail.amazonaws.com, config.amazonaws.com）を付け足したところ、エラーにならずに進めました。

https://docs.aws.amazon.com/ja_jp/controltower/latest/userguide/getting-started-with-control-tower.html

```json
{
  "Sid": "Allow CloudTrail and AWS Config to encrypt/decrypt logs",
  "Effect": "Allow",
  "Principal": {
    "Service": [
      "cloudtrail.amazonaws.com",
      "config.amazonaws.com"
   ]
  },
   "Action": [
      "kms:GenerateDataKey",
      "kms:Decrypt"
   ],
    "Resource": "*"
}
```
Headerを中央、右ぞろえにする方法


Header の中央にタイトル、右端に各機能など配置したいときありますよね。
ちょうどこんな感じです。(個人製作アプリですみません。。。)

![music.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1782673/6488c657-f9ab-9e1b-322f-b1caf79d23f1.png)

私は、基本 flexbox を使用しているのですが、flexbox の機能だけではできない、実装です。

そういった場合、relative と absolute を使うとうまく実装できます。

```react
  <div className="relative flex justify-center">
    <h1>中央のタイトル</h1>
     <div className=" absolute right-0 ">
      <div className="flex">
         <div>Japan</div>
         <div>USA</div>
        <div>China</div>
      </div>
    </div>
  </div>
```

是非お試しあれ。
macOS CatalinaとmacOS Big SurはTime Machineでのバックアップ復元における互換性がない

# 状況
先日，MacBook Pro(13inch,2020,2.3 GHzクアッドコアIntel Core i7)のディスプレイを破壊(閉じるときにオーディオプラグを挟んでしまいディスプレイのみ昇天)をしてしまったので，速攻バックアップ用のディスクを購入しバックアップをし，修理に出したらやはりクリーンインストールされて帰ってきた．そこでバックアップを復元しようとした．
しかし，移行アシスタントで移行元を探してもずっとグルグル...Time Machineから復元しようとしてもmacOSシステムのバックアップが見つかりませんでしたと表示され，復元できず．バックアップはちゃんとできているはずなのに...([^1]と同様にバックアップできていた)

# 環境
OS : macOS Big Sur v11.6.7
バックアップディスク(HDD) : TOSHIBA Canvio 1TB(HD-TPA1U3-B/N)
クリーンインストール後のOS : macOS Catalina

# 解決策
クリーンインストール後のMacBookでとりあえず新規にダイアログに沿ってユーザー等を作成する．その後，OSをmacOS Big Surにアップデートし再起動．再起動したら，移行アシスタントを開き，再度Time Machineでバックアップしたディスクを接続すると，作ったバックアップが認識された．

# 原因

原因は単純．macOS Big Surで作成したバックアップは，macOS Catalina以下とは互換性がない(バックアップのフォーマットがCatalina以前はHFS+，Big Sur以降はAPFSとなっている)ことに起因していた．[^2]
今回はたまたま互換性がないバージョン同士になってしまったというわけだった．
Catalina以前同士，Big Sur以降同士での互換性は今の所確保されているようなので，その場合は他に原因があると見て良さそう．[^3]


# 参考

[^1]:「Time Machine で Mac をバックアップする」
https://support.apple.com/ja-jp/HT201250

[^2]:「Apple、macOS 11 Big SurのTime Machin機能にAPFSフォーマットを採用。より高速でコンパクトなバックアップが可能に。」
https://applech2.com/archives/macos-11-big-sur-apfs-formatted-time-machine.html
重要: Big Surを搭載したMacでバックアップを作成した場合、そのバックアップは古いバージョンのmacOSを搭載したMacとは互換性がありません。
MacでTime Machineを使ってファイルのバックアップを作成する – macOSユーザーガイド

[^3]:「macOS 12 Montereyで作成したTime MachineバックアップはmacOS 11 Big Sur以降のMacとの前方互換性を確保。」
https://applech2.com/archives/macos12-monterey-time-machine-compatible-with-big-sur.html
Appleが2021年10月にリリースした「macOS 12 Monterey」では、このMontereyで作成したTime Machineバックアップの互換性がmacOS 11 Big Sur以上のMacで確保されています。
SORACOMのソラカメを使ってみた

# はじめに
先日行われた以下のイベントにて、[ソラカメ](https://soracom.jp/store/20834/)のプレゼントに当選しました。

https://algyan.connpass.com/event/244177/

というわけで開封の儀です。

# ソラカメとは
ハードウェアとしてはアトムテック社の販売している [ATOM Cam 2](https://www.atomtech.co.jp/products/atomcam2)をそのまま利用しています。
[ソラコムとアトムテックの業務提携](https://soracom.com/ja-jp/news/20220518-1/)により実現したようです。

# 開封
届いた箱もATOM Cam 2のまんまです。
![IMG_20220609_205419.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/0e94c67f-a1d2-443d-787a-40134f247aca.jpeg)

中身。比較対象を写しておらず恐縮ですがとても小さいです。
同封されていたステッカーを貼っておきました。
![IMG_20220609_205852.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/a737d624-f6ca-90e2-f28d-c1f9c08601d1.jpeg)


# アプリから登録
Android か iPhoneでアプリをダウンロードして作業します。
利用するアプリは通常のATOM Camと同じものです。

起動後最初のログイン画面で、下の「Soracomはこちらへ」をタップします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/b79fa9fb-811e-d57e-035c-610e9bfcc65c.png)

ソラコムのアカウントでログインします。（なんか表示が崩れてる…）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/4df3a50d-eaf4-d2c2-24f1-8c3767068694.png)

デバイスの追加ボタンをタップします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/6dd6bdd8-d04d-8408-078b-fae2b8992cd3.png)

あとは表示される手順に沿って実施すればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/97154a4b-8601-7e2c-a00c-69f295066e98.png)

QRコードをスマホに表示させてATOM Camのカメラで読み取るという手順が新鮮でした。カメラ搭載デバイスならではの手順ですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/41e8d7f8-a7f6-8e51-6e72-e91041091557.png)

# ファームウェアのアップグレード
届いた状態ではファームウェアが最新でない場合があるのでアップグレードしましょう。
`アカウント` メニューから `ファームウェアのアップグレード` をタップしてアップグレードを行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/04416259-0799-55c3-387e-f2316f9d7446.png)


# ライセンスの付与
今回のプレゼントキャンペーンでは本体に加え14日間常時録画のライセンスもいただきました。今回登録したカメラにそのライセンスを付与します。
`アカウント` メニューから `カメラのライセンス管理` をタップして登録を進めていきます。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/19552032-5f4b-c930-98cc-3cfdd2477400.png)

登録が終わると以下のように `割当数 / ライセンス保持数` が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/bec9ab8a-1837-5558-39be-4a6d17b86b80.png)

ライセンスはソラコムのユーザーコンソールから購入できます。カメラを増やす場合はこちらで購入し、アプリからカメラに割り当てましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/00eb0faa-38b2-2d80-efbd-dbfe51b7b2f2.png)

# 感想
現時点で通常のATOM Cam 2と比較したソラカメの優位性は、

- 常時クラウド録画が可能
- ライセンスをソラコム経由で購入可能

という点かと思います。
一方、ソラコムの強みである既存サービスとの連携は特になく、ソラカメ単体で閉じたサービスのようです。

[ATOM Cam 2とRaspberry Piを使ってソラコムと連携](https://qiita.com/Plemling138/items/1db6d78dcd6bd621b8b3)されている方もいらっしゃるようですが、こういったことがソラカメ単体で実現できるといいですね。今後のアップデートに期待したいと思います。

# おわりに
提供いただいたALGYANコミュニティおよびソラコム様、ありがとうございました。
Node(npm)でWebpackコマンドでエラーになる

# はじめに

「TypeScriptハンズオン」という書籍を勉強するにあたって、書籍の環境構築手順をDocker環境で構築しようと考えました。

試行錯誤して1度できたのですが、なぜか2回目にやったときにコマンド実行でエラーが発生しました。そこで発生した事象が調べたところどこにもなかったのでまとめます。

# 問題

以下のようなエラーが発生しました。

```
$ npx webpack-cli init
=> [webpack-cli] No commands found to run

$ npx webpack-dev-server
=> const maxPort = 65_535でシンタックスエラー
=> webpack-dev-server syntaxerror unexpected token =のエラーもでた
```

前に1度作成したときにはできたのになぜか同じ手順を踏んでもできなくなっていました。

# 解決方法

原因はDockerで利用している`Nodeイメージ`が**古い**ことでした
`node:10`を古い記事をみて利用していました。これを`node`に変更することでエラーなくできるようになりました

```Dockerfile
FROM node:10
↓
FROM node
```

# おわりに

ここに気付くまでにかなりの時間を費やしてしまいました。
ネットにも解決方法がなく試行錯誤して原因をつきとめるのが大変でした
【個人開発】Nuxt3(RC)とmicroCMSでWordleのJリーグ版を作ってみました

n番煎じで流行に乗り遅れてる感はありますが、WordleのJリーグ版を作ってみました。
この記事を覗きに来ている方は恐らくJリーグファミリー・サッカークラスタかと思われますので、是非！よければ！本ゲームを触ってみてあげて下さい。何卒！

https://jleague-wordle.netlify.app

# 使ったもの

<dl>
  <dt>Nuxt.js</dt>
  <dd>もうすっかりNuxtの魅力に取りつかれてしまったので使用しています。</dd>
  <dd>Nuxt3の安定板リリースももうすぐですし、楽しみですね！</dd>
</dl>
<dl>
  <dt>microCMS</dt>
  <dd>お題の管理に使用しています。</dd>
  <dd>ブログの記事管理にコンテンツ管理、そして本ゲームのようにちょっとしたデータベース的用途にも使えるmicroCMS、おすすめです！</dd>
</dl>
<dl>
  <dt>Netlify</dt>
  <dd>ホスティングに使用しています。</dd>
</dl>

# 作成の動機

「Wordle 日本語」でググったことある人あるあるだと思うのですが、__英単語の語彙力がありません__（直球）。

以下、とある日の問題の2手目で「⬛⬛⬛ER」となった私の心の声から引用です。

> 「んー、JOKERやな！もろたで工藤！」→「⬛O⬛ER」
> ↓
> 「2文字目がO…せや、LOSERや！LOSERやけど勝ったな、ガハハ！上手いこと言ってもうたわ！」→「⬛O⬛ER」
> ↓
> 🤔

となり、「xOxE」で終わる単語を思い浮かべては適当に入力し、「ROPER」「ZONER」という単語が存在するという知識を得て敗北しました（ちなみに答えは「FOYER」で、ホテルなどのロビーの意）。

そこから「Wordle 日本語」でググったものをいくつか遊んでみたのですが、自分が想像するものとは少し違い…「じゃあ作っちゃえ！」ってことで作成したものが上記になります。

お題をJリーガーにした理由ですが、私が選手の名前をよく知らないからです。自クラブの選手ならまだいいんですが、他クラブの選手となると苗字しか知らない場合が多いんですよね…
折角なので選手の名前も覚えられるように、という希望も込めてお題をJリーガーにしました。


後はJリーグが好きだからです。海外サッカーも面白いけど、こんな面白いリーグ世界広しといえどなかなか無いですよ！Jはいいぞ！

# 作成するにあたって気を付けたこと

#### 見た目

本家を徹底的に~~パクる~~参考にすることです。UI、アニメーション、リザルトに結果のシェア方法など、概ね本家に近い形で作ったつもりです。

#### お題の単語数

お題の単語数に関してはオリチャーを発動し6文字にしています。これはなぜかというと、**何となく名前を思い浮かべた選手2名の名前が6文字だったから**です。何か深い考えがあったという訳ではありません。
全くの偶然ですが、結果的に6文字の選手名が多くて助かりました。Jリーガーの名前の文字数について考えることが人生において多い訳ではなかったので僥倖です。

#### 英語と日本語の違い

本家Wordleでは26文字から6回の試行で解答を導きますが、日本語は46文字に加え濁音・半濁音等もあり、計82文字にもなります。
このままではとても解答まで辿り着けそうにも無いので、再びオリチャーを発動！ヒントを本家の2パターンから4パターンに増やすことで解消（多分）。具体的には濁音・半濁音等を区別しないようにしたので、実質46文字+αから試行することになります（「た」で入力した場合、「だ」も検索する）。
一応作っている最中に自分で遊んでいた感じでは7割弱は解けていたので、解消されている！はず…（遊んで感想を頂ければ幸いです）

#### お題のデータ

こちらも本家を参考に人力で行いました。というか**人力でやる以外の方法を持ち合わせていません**。ここが一番大変でしたが、DAZNで試合見ながらやってたので何とかなりました。地産地消（ん？）。

以下[ファミ通さんの記事](https://www.famitsu.com/news/202203/25255891.html "『Wordle』世界的ヒットした単語当てゲームの作者が明かす、セオリーを外れまくった開発の裏側【GDC 2022】")より引用。

> もうひとつの違いは、お題用の辞書にめちゃくちゃたくさんの単語を収録していたこと。
>
> ～中略～
>
>そこで絞り込みを行うことになるのだが、頻出単語などを抽出していくアルゴリズム的手法はうまくいかず、結局選んだのは人力作戦。当時何か没頭するものを必要としていたパートナーに「知ってる」「知らない」「多分知ってる」の三択で答えるシステムを作り、分類してもらったのだとか。

その際色々なクラブのサイトを見て回ったのですが、これが意外と面白かったです。普段は自クラブのサイト以外あまり見る機会無いですし。その中でも鹿児島ユナイテッドFCの選手一覧は印象的で、全58クラブ中、地域別で選手一覧を表示していたのは鹿児島だけでした。やはりユニークなものは印象に残りますね。

また、選手プロフィールにSNSのリンクを載せているクラブには助けられました。本物かどうかを確かめる手間が省けました。届くかどうかはわかりませんが、謝意をば！

# 最後に

ここまで目を通してくれた~~奇特な~~風変りな方がいれば、改めてにはなりますが、是非とも本ゲームを触ってみてください！更に結果をSNSでシェアとかして貰えたら嬉しいなー、なんて。

本ゲームを通して試合観戦の際などに、

「あっ、この選手、この前のお題の選手だ！」

みたいになって、その選手に注目するきっかけになってもらえれば作った甲斐があります。何卒！
react stateについて

# はじめに

stateの機能を利用することで状態遷移のロジックを簡潔かつ明示的に記載できます。
形式的に呼び出して、複雑な状態遷移の処理を数行で表現することが可能です。

また、React 16.8 でhookという新機能が追加され、state などの React の機能を、クラスを書かずに使えるようになりました。
hookが実装される以前はstateなどの機能を利用する為にクラスコンポーネント表記が一般的だったようです。
hookの実装により、関数コンポーネント表記でもstateなどの機能を利用することができるようになり、実装が比較的簡単にできるようになりました。

実際にクラスコンポーネントでのhookの利用した経験はないですが、関数コンポーネントでの実装とコードを比較すると理解するまでに時間がかかりそうでした。

# ステートフック

- 例
```tsx
 const [count, setCount] = useState(0);
```

useStateの引数はこのstateの初期値となり、countの値は"0"となっております。
setCountはcountの値を更新するための関数となっており、これを介してのみcountの体を変更することが可能です。

- クリックする度にカウントが進んでいく例
```tsx
<button onClick={() => setCount(count + 1)}>
    Click me
</button>
```

また、他のhook機能と組み合わせることで他にも色々なことができます。

# その他フック
## effect
stateを渡してあげることで、レンダーのタイミングを制御できる
```tsx
useEffect(() => {
    console.log("レンダーされました。");
}, [state]);
```

## context
スタイルの状態遷移を管理できる
```tsx
const themes = {
  light: {
    foreground: "#000000",
    background: "#eeeeee"
  },
  dark: {
    foreground: "#ffffff",
    background: "#222222"
  }
};

const ThemeContext = React.createContext(themes.light);

function App() {
  return (
    <ThemeContext.Provider value={themes.dark}>
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar(props) {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return (
    <button style={{ background: theme.background, color: theme.foreground }}>
      I am styled by theme context!
    </button>
  );
```


# あとがき
まだreactをはじめて間もないですが、もっと知見を深めて、今後有益な情報を発信できたらと思います。
Step Functionsで動的並列処理

# 概要

Step Functions でワークフローを組む際、前段の出力が可変長になることがある。こういうときに次段の並列数を動的に決定したい。これを叶えるための機能が存在するので実際に試してみた。

機能の解説は参考リンクに譲るとして、ここではコンソール画面から実際に設定、実行するまでの手順を書いていく。

# 設定方法

## 全体のワークフロー

Map を置いてその下に繰り返したい処理を入れる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193600/7a6a1117-7181-e264-9aa4-baf45dc66a31.png)



今回 Lambda 関数は Python3.9 で以下の様に実装している。

```python3
import json

def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'body': json.dumps({"count": event.get("count")})
    }
```

## Map の設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193600/3a13547a-33ee-f5a6-5d54-504bf18a6620.png)


「項目配列のパス」には反復処理したい配列へのパスを指定する。今回は入力として以下のような形を想定しているので `$.counts` を入れておく。

```json
{
  "counts": [1, 2, 3, 4, 5]
}
```

このままだと Lambda への入力が数字だけになってしまうので、前述の関数のように `event.get("count")` で受け取れるように配列項目の変換を行う。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193600/1cf79661-36c0-fc01-b85d-f9854d1a8ae2.png)

関数内では `count` というキーで取得したいので以下のように変換を行う。他にも `$$.Map.Item.Index` でインデックスを取得したりもできる。

```json
{
  "count.$": "$$.Map.Item.Value"
}
```

今回、出力、エラー処理に関しては特に修正しない。

## Lambda: Invoke の設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193600/d2649012-09c4-42f7-330b-a688c3df8357.png)


ちゃんと想定の関数を指定する。だけ。

# 実行

以下で入力を与えて実行をしてみる。

```json
{
  "counts": [
    1,
    21,
    39,
    40,
    52,
    68
  ]
}
```

Lambda 関数の入力は想定通り以下の様になっている。

```json
{
  "count": 1
}
```

出力は以下。

```json
{
  "statusCode": 200,
  "body": "{\"count\": 1}"
}
```

コンソール上から入力配列の各項目に関する結果を見ることができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193600/d801fc9c-f1f6-d4e2-c726-b79df65285fc.png)

入力の配列数を変えると起動される Lambda の個数も変わることが確認できる。便利。

# 参考 Links

https://aws.amazon.com/jp/blogs/news/new-step-functions-support-for-dynamic-parallelism/

https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/amazon-states-language-map-state.html
unityでeditor2019プロジェクトを2020にアップグレードするとコンパイルエラーが生じるのを直す話。

unity 2019から unity 2020にバージョンアップした後、エディターを開いてコンパイルが始まるとエラーが多発しました。


## エラー内容

下のようなエラーが出ます。
```
error CS0535: 'CollabToolbarWindow' does not implement interface member 'IHasCustomMenu.AddItemsToMenu(GenericMenu)'
```

他に多様なエラーが10個ほど出ました。

## 原因と解決法

https://forum.unity.com/threads/unity-collaborate-1-8-0-broke-my-project.1165088/

ここでの投稿曰く


>For 2019 versions of the Editor, please use v1.6.0, v1.8.0, and subsequent Version Control versions with an even-numbered minor version.
>For 2020+ versions of the Editor, please use v1.7.1, v1.9.0, and subsequent Version Control versions with an odd-numbered minor version.

とのことで
要するに、エラーを出しているプラグインが2019では偶数、2020では奇数バージョンが必要とのことで、これを更新してあげればうまくいきそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173847/74cc74d2-befc-4fca-a62f-094923f68cc9.png)

パッケージマネージャにて上のようにバージョンを選んで2020向けの奇数バージョンを改めてインストールしてあげると無事にビルドが通り、エラーが解消します。

### 余談
なぜunity2019を使っているのか？
VRM、VRChatなどのライブラリをいじるには2019対応が多く、なかなか移行していませんでした。
EC2インスタンス作成の流れとAMIについて（自分用メモ

Amazon EC2（Amazon Elastic Compute Cloud）は、AWS上で動作する仮想サーバーを提供するサービス。
Amazon EC2などAWSが提供する仮想サーバーのことを「インスタンス」という。

・EC2インスタンスの作成の流れ
1、 Amazonマシンイメージ（AMI）の選択
2、 インスタンスタイプの選択
3、 インスタンスの詳細の設定（ネットワーク、ユーザーデータ、プレイスメントグループなど）
4、 ストレージの追加
5、 タグの追加
6、 セキュリティグループの設定
7、 キーペアの設定


・Amazonマシンイメージ（AMI）とは
Amazonマシンイメージは、EC2インスタンスに展開可能なOSやミドルウェアなどのテンプレート。EC2インスタンスはAMIから作成。
EC2インスタンスに展開するAMIは、AWSから提供されるイメージの他に、独自や他のユーザーが作成したもの、AWS Marketplaceに掲載されているものを選択できる。選択したAMIをEC2インスタンスに展開して、テンプレートと同じ構成のインスタンスを起動する。
AMIは「EC2 Image Builder（AMI管理用のAWSサービス）」で作成する方法の他、既存のEC2インスタンスから作成することもできる。


※EC2インスタンスの作成時にAmazonマシンイメージ（AMI）からOSの導入が行われるが、EC2インスタンス固有のOSの設定や、AMIに入っていないミドルウェアの導入はユーザーが実施する必要があるので注意。
iOS開発で知っておきたいnilの知識

# 概要
iOSアプリの開発をかれこれ２年以上やってますが、
未だにソースレビューやエラーで引っかかるのが、「nil」や「null」
絡みなんですよね。。

特にSwiftの場合、
```
unexpectedly found nil〜
```
といったエラーがによく引っ掛かります。

製造工程にて、nilについてどう扱えばいいのか？
最低限の知識を軽くまとめておきたいな。。

そんなことをふと思ったので簡単にまとめておきたいと思います。

### optionalについて
SwiftにはOptionalという概念があります。
簡単に言えば<font color="Red">空の値を保持できるようにした変数</font>を指します。

この空の状態を、Swiftの場合「nil」という表現で表します。
### 例
```swift
// optional型
var hoge?: String? // nilとして初期化される

// 非オプショナル型
var hoge2: String

hoge = nil 　　　// OK
hoge2 = nil // ERROR
```
上記のように、Optional型ではない変数にnilを
代入するとERRORとなります。

あまり他の言語にはないルールじゃないですかね。。。？

:::note warn
注意
非Optional型にnilが代入された場合アプリが落ちます。
初心者の方でアプリが落ちた場合はまずこれが原因と疑っても問題ないくらいです。
:::

# Optional型の注意事項
じゃあ全部Optionalにしてしまえばいいと思われますが、
実は使用するにあたり注意したいことがあります。

### Optionalと非Optionalは同じ操作はできない
例えばInt型とOptionalのInt型は異なる型になります。
よって同じ操作はできません。
### 例
```swift
var number: Int = 10
var optNum: Int? = 20

number + 10 // 20
optNum + 10 // ERROR
```
「10」はInt型と判断されるため、Int？型に代入すると
エラーになります。

なのでOptional型を非Optional型に変換する必要があります。
これを<font color="Red">アンラップ(unwrap)</font>と言います。

ではアンラップはどうすればいいか見てみます。
# アンラップの例
### ①強制アンラップ
対象変数の最後に「!」をつける方法です。
### 例
```Swift
var number: Int? = 10
print(number)  // 実行結果：ERROR
print(number!) // 実行結果：10
```
シンプルな方法ですが、対象の値が「nil」の場合はエラーになります。

:::note alert
警告
対象のOptional型変数が「nil」の場合、
アンラップしてはいけない！
:::

### ②nilチェック
①の方法を避けるべく利用されるのが、
みんな大好きnilチェックです。

単純に値がnilかどうか判断し、
処理を分岐してあげることですね！

### 例
```Swift
var optStr: String? = "optional"

if let str = optStr {
   // nil以外の場合に実施する処理
}
```

# 最後に
簡単ですがSwiftを使用する際の注意事項を
まとめました。

・nil許容せず変数を使ってたらアプリが落ちた！
・アンラップしたらエラーが出た！
などのミスで引っかかったり、レビューで突っ込まれてから気づくということが
ありがちなのでこの記事がお役に立てれば幸いです！

ちなみにObjecive-CではnilだのNULLといった違いが
また出てくるみたいですね。

時間がある時に別途記事を作成できたらと思います！
本記事を閲覧いただきありがとうございました！

何か間違いがあればご指摘いただけると幸いです。