OmniAICreator/Qiita-1.07M huggingface dataset:
【初心者向け】Windowsで開発環境を整える。

# 目的
・新規購入したのWindows PCで開発環境を新規作成する。
・WSL, Docker, VSCodeの3つを本記事で導入する。

# 動作環境
OS: Windows 11
CPU: 11th Gen Intel(R) Core(TM) i7-11800H @ 2.30GHz   2.30 GHz
MEM: 32GB

WSL:1.2.5.0
Docker for Desktop: 4.20.1

# WSLの導入
[WSLのインストール](https://learn.microsoft.com/ja-jp/windows/wsl/install)をもとに作業を行いました。

1. 管理者としてターミナルを実行
    検索欄から、`terminal`を検索し、「管理者として実行」を選択。

1. ターミナルで`wsl --install`を実行
![スクリーンショット 2023-06-07 105219.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3243437/03870bab-25cc-fdb1-5e2c-f876f9a0e416.png)

1. Linuxユーザー情報を設定する
   [WSL 開発環境を設定する](https://learn.microsoft.com/ja-jp/windows/wsl/setup/environment)を参考に、環境設定を行う。
    3-1. 再度`wsl --install`コマンドを実行すると、ユーザー名・パスワードを求められるので、それぞれ適当なものを入力してください。このときパスワードは入力しても表示されません。
![スクリーンショット 2023-06-07 110618.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3243437/86db7634-b923-e1a0-8011-cb7162d7d985.png)

    3-2.　`sudo apt update && sudo apt upgrade`コマンドを利用してパッケージのアップデートを行う
    定期的に行ったほうが良いみたいです

    3-3. `exit`コマンドでwslの終了ができます。これで一旦はwslの環境設定を完了とします。再度wslを実行したい場合はターミナルで`wsl`を打てばいい様です
    
# Docker for Desctop
1. [Dockerのインストールページ](https://docs.docker.jp/desktop/windows/wsl.html)から、Docker Desktop for Windows をダウンロード
1. ダウンロードしたインストーラーを起動・実行してください。このときPCの再起動が行われるので気を付けてください。
1. 再起動が完了した後、ターミナルを再度開いて`wsl`コマンドを実行。
`docker ps`コマンドを実行して以下のように出てくれば問題なくインストールができています。
```
amegumo@MSI:~$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
```

# VSCode
[WSLでVS Codeの使用を開始する](https://learn.microsoft.com/ja-jp/windows/wsl/tutorials/wsl-vscode)を参考に作業を行います。
1. [VS Code のインストール ページ](https://code.visualstudio.com/download)から、Windowsを選択してダウンロードします。
    ダウンロード時に「PATHへの追加(再起動後に使用可能)」が選択されていることを確認し、インストール。
![スクリーンショット 2023-06-07 114647.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3243437/125eb480-1292-0157-6827-173b89216b20.png)

1. インストール後、再起動をしてください。再起動後、wsl画面で`code`コマンドを実行したらVS Codeが立ち上がると思います。

# 備考
・再起動時にDockerが起動していない場合
Docker for Desktop > Settings > Generalを開き、`Start Docker Desktop when you log in`にチェックが入っているかを確認してください。
チェックをいれれば毎回PC起動時にDockerが起動するようになります。
![スクリーンショット 2023-06-07 120358.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3243437/98f873b0-6529-aaae-fbe2-2b5b66a67cb2.png)

# 参考
・[WSLのインストール](https://learn.microsoft.com/ja-jp/windows/wsl/install)
・[WSL 開発環境を設定する](https://learn.microsoft.com/ja-jp/windows/wsl/setup/environment)
・[Dockerのインストールページ](https://docs.docker.jp/desktop/windows/wsl.html)
・[WSLでVS Codeの使用を開始する](https://learn.microsoft.com/ja-jp/windows/wsl/tutorials/wsl-vscode)
・[VS Code のインストール ページ](https://code.visualstudio.com/download)

# 以上
お付き合いいただきありがとうございました。
間違いやより良い導入方法・他に導入すべきものなどご指摘がございましたらコメント等をお願いいたします。
MongoDB AtlasのGraphQLを呼び出すためのクロスドメイン制約回避: Proxy使用

## 概要
GitHub pgesに公開した静的コンテンツからMongoDB AtlasのGraphQLを呼び出す場合、
MongoDB AtlasのBearer認証により、クロスドメイン制約を回避することができる。
ただし、Bearer認証で取得するアクセストークンは30分間隔で更新が必要である。

https://qiita.com/tthogho1/items/9be1e2506cc703a825ee

他の回避策として、Proxyを使用してGitHub pgesと、MongoDB Atlasを同一ドメイン
とみせることにより、クロスドメイン制約を回避させてみた。

下図の構成だと別ドメインでエラーになるので、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284235/ee454f10-41f9-30ca-ee2d-b4cc91c152d4.png)

以下のような構成を組んでみた。Lambdaをはさんだのは、CloudFrontから直接Mongodb Atlasの接続がエラーになり、すぐ解決しそうになかったから。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284235/c0e14a67-ef18-9824-d393-344f703879f8.png)



### GraphQLを呼び出すLambdaを作成
fetch APIが組み込まれている node v18を使用した。Lambda作成後、CloudFrontのオリジン登録用に、Lambda関数URLを生成した。

```typescript
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';

export const lambdaHandler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
    const bound = JSON.parse(event.body);

    const queryMsg = `query {
  		webcams(query:{status:"active",location:{
                        longitude_lt:${bound.longitude_lt},
                        longitude_gte:${bound.longitude_gte},
                        latitude_lt:${bound.latitude_lt},
                        latitude_gte:${bound.latitude_gte}}}
    	,limit:200
    	,sortBy:ID_ASC) {
			id
			title
    		location{
     		 	latitude
      			longitude
    		}
            player{
               day{
                 available
                 link
              }
           }
           image{
                current{
                    thumbnail
                }    
           }
  		}
	}`;

    try {
	    const response = await fetch('https://realm.mongodb.com/api/client/v2.0/app/webcamql-qrkjj/graphql', {
  		    method: 'POST',
  		    headers: {
			    'apikey': '<apikey>' ,
    		    'Content-Type': 'application/json'
  		    },
  		    body: JSON.stringify({
      		    query: queryMsg
  		    })
	    });
        const webcamsJson = await response.json();
        return {
            statusCode: 200,
            body: JSON.stringify(webcamsJson.data.webcams),
        };
    } catch (err) {
        console.log(err);
        return {
            statusCode: 500,
            body: JSON.stringify({
                message: 'some error happened',
            }),
        };
    }
};
```

### CloudFront側の設定
Lambda関数URLを作成後、Github pagesとLambda関数URLをCloudFrontのCloudFrontのOriginに登録。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284235/5038523e-420e-0347-cd31-77cea6d91984.png)

<cludfrontドメイン>/nuxt3-app/は、Github pagesのパス、それ以外はLambda関数を呼び出すよにうに、CloudFrontのBehaviorsに登録。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284235/f3e6c467-5c36-e874-e6fb-51e785ecf60f.png)

Lambda通すと、反応が遅いしそもそもAWSだと無料にならない。
Flutterでリストから選択した項目をAppBarに表示するアプリを作成する

# まずは、完成したアプリケーションのスクリーンショットを見てみる
![スクリーンショット 2023-06-07 11.49.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3268288/14e6fa3d-2813-2f6d-07ea-7a8c7ce539e3.png)
![スクリーンショット 2023-06-07 11.49.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3268288/8d1bc1f5-b127-be55-5594-4cdac0a7a674.png)

このアプリケーションのコードは、chatGPTから提供されたものを基に作成し、一部書き換えた。

## 私の要求
「Flutterでアプリを作りたい。Stringのリストがあるが、その中から一つだけ選択可能としたい。選択されたStringを画面のトップに表示させたい。」
# コード：
```dart
import 'package:flutter/material.dart';

void main(){
  runApp(MyApp());
}

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      home: MyHomePage()
    );
  }
}

class MyHomePage extends StatefulWidget {

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<String> stringList = ['One', 'Two', 'Three', 'Four', 'Five'];
  String selectedItem = '';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(selectedItem.isEmpty ? 'No Item Selected' : selectedItem),
      ),
      body: ListView.builder(
        itemCount: stringList.length,
        itemBuilder: (context, index){
          return ListTile(
            title: Text(stringList[index]),
            onTap: () {
              setState(() {
                selectedItem = stringList[index];
              });
            },
          );
        },
      )
    );
  }
}
```

# コードの解説
- ListView.builderを使用すると、指定したitemCountの数だけ、動的にリストアイテムを生成する。itemBuilderコールバックは各インデックスで呼ばれ、そのインデックスに対応するウィジェットを生成する。
```dart
 body: ListView.builder(
        itemCount: stringList.length,
        itemBuilder: (context, index){
```
- ListTileウィジェットはリストの各アイテムをタップ可能な項目として表示する。ここではtitleにTextウィジェットを使い、各項目のテキストとしてstringListの対応するインデックスから文字列を取り出して表示する。
```dart
          return ListTile(
            title: Text(stringList[index]),
```
- 各リストアイテムはonTapコールバックを持っており、タップされた時に実行される関数を定義する。ここでは、setState()メソッドを使い、selectedItemをタップされたアイテムの文字列(stringList[index])に設定する。これにより選択したアイテムが追跡され、AppBarに表示される状態が更新される。
```dart
            onTap: () {
              setState(() {
                selectedItem = stringList[index];
              });
            },
          );
```

以上のコードを使用すると、stringList内の各文字列がリストビューに表示され、ユーザーがアイテムをタップすると、そのアイテムがAppBarに表示される。このアプリケーションでは、一度に一つのアイテムしか選択できないようになっている。
【ChatGPT無】実験：回答結果を固定するのに、どこまでやるか


　どうも、カーブミラーです。

　今回は、
　　プロンプトをどこまで、
　　　詳細にすれば、
　　　　結果が定まるのか、です。
***
　まずは、最初のプロンプト。
>ウェブアプリ作成する上で必要なのは？

　ここから、
　　出力に応じて、
　　　プロンプトに
　　　　条件などを追加していく。
　　　　　そして、再送。

　　その作業を
　　　25回も繰り返し
　　　　……。

　最終的に
　　出来上がったプロンプトが
　　　こちら。
```Text:最終プロンプト
ウェブアプリ作成する上で必要なものは？

#上記指示の注意点
「考慮条件」と「注意点」と「備考」を考慮してください。

#考慮条件
スマホ単体での利用。
サーバアクセスなし。
テキストエディタあります。
HTML+CSS+JavaScriptの知識、あります。
データベース、使用せず。
セキュリティ対策、考慮せず。
ホスティングやデプロイメント、なし。

#注意点
箇条書きをひと言で。
「:」または「：」以降の説明はいりません。
解説・説明はのちほど聞きます。

#備考
なお、私はプロの開発者ではありません。専門用語は苦手です。
説明過剰は、やめてください。
理解できません。
```

　結果。
　　３回、再送。
　　　内容は、
　　　　スマホについてが
　　　　　変わったくらい。

>ウェブアプリ作成に必要なものは次の通りです：
>
>テキストエディタ
HTML
CSS
JavaScript
スマートフォンのウェブブラウザ

　私としては、

>アプリとしての目標
アプリとしての機能
画面デザイン

　このあたりが
　　残ってくれるかなぁ、
　　　と思っていたのに、
　　　　この結果。

　残念。
***
　実は、
　　スマホの機能を
　　　ブラウザで確認したい
　　　　と思っての
　　　　　プロンプト作成でした。

　うん、
　　スマホアプリを
　　　作りたいのですよ。

　とはいえ、
　　具体的な目標が
　　　あるわけでもなく……。

　えっ、家計簿アプリ？
　　あれは、題材としてですから。
　　　それに、いいアプリ、
　　　　たくさん、ありますし。

　とにもかくにも、
　　まずは、
　　　どの機能が使えるのか、
　　　　が問題なので、
　　　　　知りたいと思った次第。

　次からは、
　　コードに
　　　持っていきたいなぁ……。

　と、
　　遠くを見る
　　　カーブミラーでした。
【Python】環境変数Pathに拒否反応を示している人に捧ぐ

# 初めに
Pythonの初回セットアップやバージョンアップの際に環境変数周りで悩まされた人は多いと思います。
私もその一人で、環境変数という言葉が出てくるたびに嫌な思いをしてきました。
そこで今回はセットアップ時の憂鬱を少しでも減らすために、環境変数についてまとめてみました。

# 環境変数
環境変数とはOSに保持させている変数です。
OS側が持っている変数のためPythonを消去しようが環境変数は残ります。

また、環境変数には「システム環境変数」と「ユーザー環境変数」の2種類があってこれはスコープの範囲を表しています。
システム環境変数はシステム全体で使われる変数で、ユーザー環境変数はそれぞれの個別のユーザーに対して使われる変数です。

# 環境変数Path
```text:環境変数Path
C:\Python\PythonXX
```
環境変数Pathを覗いてみるとこのようなパスが記載されていると思います。

しかし、そもそもPythonの環境構築で環境変数Pathを通す意味とはなんでしょうか。
本来、Pythonのスクリプトファイルの実行を行うには以下のようにコマンドを打つ必要があります。

```text:本来の実行コマンド
C:\PythonXX\python.exe [スクリプトのパス]
```

自分が使いたいバージョンのpython.exeの配置場所を絶対パスで指定してあげるんですね。

でも、みなさんが実行するときはいちいち絶対パスを指定したりはしていないと思います。
以下のようなpythonコマンドを使って実行しているのではないでしょうか。

```text:pythonコマンドを用いた実行
python [スクリプトのパス]
```

pythonコマンドは環境変数Pathで指定したパスにあるpython.exeを実行するコマンドなので、最初のコマンドと同じ動きをします。このコマンドと環境変数Pathのおかげで、絶対パスをいちいち打つことなく実行できるようになっています。

# 環境変数の汚染例
```text:環境変数Pathの例
C:\Python\PythonXX;C:\Python\Scripts
```
環境変数には複数のパスを指定できるので、必要があれば適宜追加していくという流れになります。
複数指定した場合はどうなるかというと、指定した順にディレクトリ内を検索していき最初に見つかったpython.exeを用いるという挙動をしています。

では、Python3.8からPython3.9に上げた際に**環境変数Pathに3.9のパスを追加する**とどうなるでしょうか？


```text:3.8と3.9のパスが同居している状態
C:\Python\Python38;C:\Python\Python39
```

Python3.9を入れたのにも関わらずPython3.8の方が先に検索対象になるため、**pythonコマンドを使った際は3.8のまま実行される**という現象が起こります。
バージョン違いのPythonをインストールしていたり、Anacondaで環境変数を自動で通してもらったりしているとおかしな挙動をするのはこれが原因だったんですね。

# まとめ
Pythonの環境構築の際に環境変数周りで問題が起きたときに気を付けることは、

**環境変数Pathに、自分の使いたいバージョンより先に別バージョンのパスが通っていないかです。**

別バージョンのパスが残っている場合は削除しましょう。
ただし、環境変数はpythonコマンド以外にも参照されるものなので削除の際は関係のないパスを削除しないように気を付けましょう。
paiza.ioでelixir その229

# 概要
paiza.ioでelixirやってみた。
良いコードを見つけたので、やってみた。

# 参考にしたページ。

https://qiita.com/nori-channel/items/93cc5bdaac817a36b7d3

# サンプルコード

```
2+5
|> IO.inspect
2+5==7
|> IO.inspect
String.length("the")
|> IO.inspect
255
|> IO.inspect
0b0110
|> IO.inspect
0o644
|> IO.inspect
0x1F
|> IO.inspect
3.14
|> IO.inspect
#.13
|> IO.inspect
1.0e-10
|> IO.inspect
true
|> IO.inspect
false
|> IO.inspect
:foo
|> IO.inspect
:foo == :bar
|> IO.inspect
is_atom(MyApp.MyModule)
|> IO.inspect
:crypto.strong_rand_bytes 3
|> IO.inspect
"Hello"
|> IO.inspect
"dziękuję"
|> IO.inspect
"foo
bar"
|> IO.inspect
"foo\nbar"
|> IO.inspect
2 + 2
|> IO.inspect
2 - 1
|> IO.inspect
2 * 5
|> IO.inspect
10 / 5
|> IO.inspect
div(10, 5)
|> IO.inspect
rem(10, 3)
|> IO.inspect
-20 || true
|> IO.inspect
false || 42
|> IO.inspect
42 && true
|> IO.inspect
42 && nil
|> IO.inspect
!42
|> IO.inspect
!false
|> IO.inspect
true and 42
|> IO.inspect
false or true
|> IO.inspect
not false
|> IO.inspect
#42 and true
|> IO.inspect
#not 42
|> IO.inspect
1 > 2
|> IO.inspect
1 != 2
|> IO.inspect
2 == 2
|> IO.inspect
2 <= 3
|> IO.inspect
2 == 2.0
|> IO.inspect
2 === 2.0
|> IO.inspect
:hello > 999
|> IO.inspect
{:hello, :world} > [1, 2, 3]
|> IO.inspect
name = "Sean"
|> IO.inspect
"Hello #{name}"
|> IO.inspect
name = "Sean"
|> IO.inspect
"Hello " <> name
|> IO.inspect

```

# 実行結果

```
7
7
3
255
6
420
31
3.14
3.14
1.0e-10
true
false
:foo
:bar
true
3
"Hello"
"dziękuję"
"foo\nbar"
"foo\nbar"
4
1
10
2.0
2
1
42
true
nil
false
true
42
true
true
true
true
2
2
2
3
2.0
2.0
999
[1, 2, 3]
"Sean"
"Hello Sean"
"Sean"
"Hello Sean"
```

成果物

https://paiza.io/projects/dKvFXuprccUE2vauWCSzcA

以上。
Windowsでpm2を再起動時に実行したい

1. pm2 saveしておく
1. フォルダパスのところに```shell:startup```
1. batファイルをつくる（名前はstartuppm2.bat)

```bat
pm2 resurrect
pm2 restart 0
exit
```

これでOK
なぜか社用ソフトのサーバ機がWindows11 Homeで、たまにアップデートしてしまっても大丈夫……。
AWS DatasyncでXアカウント先のロケーション作成がエラーになる場合

## 状況
とあるバケットから別のアカウントのバケットにファイル転送の設定を行う際に[チュートリアル:Amazon S3 から Amazon S3 へデータを転送するAWS アカウント](https://docs.aws.amazon.com/ja_jp/datasync/latest/userguide/tutorial_s3-s3-cross-account-transfer.html)に沿って実施したところ、

[ステップ 4: S3DataSync バケットの宛先ロケーションを作成する](https://docs.aws.amazon.com/ja_jp/datasync/latest/userguide/tutorial_s3-s3-cross-account-transfer.html#s3-s3-cross-account-create-datasync-destincation) で下のエラーで進めなくなりました


> An error occurred (InvalidRequestException) when calling the CreateLocationS3 operation: DataSync location access test failed: could not perform s3:HeadBucket on bucket account-b-bucket. Access denied. Ensure bucket access role has s3:ListBucket permission.

## 原因と解決方法

良く良く考えてみると当然で、送信先のバケットポリシーには、送信元のロールしか許可していない訳ですので...

```policy-before.json
"Principal": {
    "AWS": "arn:aws:iam::account-a-id:role/name-of-datasync-role"
},
```

ですので、ロールの他にコマンドを実行するIAMユーザを追加したところ、無事宛先ロケーションを作成できました

```policy-after.json
"Principal": {
    "AWS": [
        "arn:aws:iam::account-a-id:role/name-of-datasync-role",
        "arn:aws:iam::account-a-id:user/name-account-a-iam-user"
    ]
},
```
(権限最小限の法則に乗っとり、宛先ロケーション作成後にIAMユーザの設定は削除しました)


同じ原因で詰まっている方のご参考になりましたら
競プロなにそれおいしいの？から食べ物でないと気づくまで（A問題解けるくらいまで）

### はじめに
最近はやたらと``競プロ``や``AtCorder``という言葉を聞く機会が増えた気がします。
私の大学の友達も「今日の*ビーモンダイ*簡単だったね」や「今日のコンテスト*ゼンタンサク*使ったら*ティーエルイー*だったわ」など耳馴染みのない第二言語のような言葉が飛び交うようになったので、これは私も始めないとと思い全く分からないながらも競プロデビューしました。

この記事ではそんな競プロ何それ美味しいのっていう状態から~~食べ物ではない~~（冗談です）今日はA問題の過去問解こう！となるまでの過程をまとめてみました。

### そもそも競プロって何？
> 競技プログラミング（競プロ）は、プログラミング技術を競うコンピュータサイエンスの競技です。競プロでは、与えられた問題に対してアルゴリズムやデータ構造を使用して解答を作成し、その正確性と実行時間の効率性を競います。
競技プログラミングの目的は、与えられた問題を最も効率的に解決するアルゴリズムを見つけることです。参加者はプログラムを作成し、問題の入力に対して正しい出力を生成する必要があります。(GPT回答)

GPTも言っているようにシステム開発の実装などではなく、アルゴリズムを用いて回答するので実際のWebアプリ開発等の実装とは異なります。

### おすすめ記事

勉強していくときにお世話になったQiita記事を共有しておきます

https://qiita.com/KoyanagiHitoshi/items/3286fbc65d56dd67737c

* 網羅的に競プロに必要な文法や書き方ついて学べるのでおすすめです

https://qiita.com/cotrpepe/items/1f4c38cc9d3e3a5f5e9c

* 遅かれ早かれ、競プロをやっていると計算量というワードが飛び交います。個人的に計算量を理解するのに一番分かり易かったです

https://qiita.com/e869120/items/b4a0493aac567c6a7240

* 最低限の数学的知識を教えてくれる記事で数学苦手な私も助けられました。

### 解く中で学んだテクニックのメモ（雑記）
Pythonで競プロ行う中で自分が詰まった点や知らなかった点を雑多に書いているので誰かの役に立てば幸いです
下記に書いてある内容は私のgitHubに書いてあるTILからの抜粋です。自分用なので見づらかったらすみません...

### 入力系

```python
s = input() //文字列
n = int(input()) // 数値
a,b = map(int,input().split()) //複数の数値
m = list(map(int,input().split()))　// 数値のリスト
```

### よく使う文法

**リストの要素のインデックスの取得**

Python のリスト（配列）の要素のインデックス、つまりその要素が何番目に格納されているかを取得する方法

リストの要素が重複していない場合、`index()メソッド`を使う

[この問題で出てきた](https://atcoder.jp/contests/abc113/tasks/abc113_b)

### テクニック系

**数値の判定**
数値であるか判定するには`isdigit関数`を用いることで判定出来る

数値なら=> `True`
それ以外なら　=> `False`

**python でのスライス**

_注意点_

最後のインデックスで指定した数から`1引いた数`までスライスされる。

[この問題で間違えた](https://atcoder.jp/contests/abc084/tasks/abc084_b)

[Python のスライスについて詳しく](https://www.sejuku.net/blog/44850)

**文字を繰り返す方法**

文字は`文字 * 数値`で繰り返すことができる

```python
ans  = "a" * 100
print(ans)

# aが100個出力される
```

[この問題で知った](https://atcoder.jp/contests/abc152/tasks/abc152_b)

**数値からアルファベットの変換**

Python の標準関数の`chr関数`を使う。
chr 関数は、ASCII コードにしたがって、数字からアルファベットや記号に変換してくれる。

ビルドイン関数だからインポートしなくていい

ちなみにアルファベットから数値の変換は`ord関数`を用いる

問題

[この問題で出てきた](https://atcoder.jp/contests/abc218/tasks/abc218_b)

回答例

```python
for i in range(26):
    ans += chr(ord('a') + p[i] - 1)
#ordで最初の文字の数値を取得それに数値を足していって、文字列変換してる
```

### 終わりに
まだまだ私も勉強を始めたばかりですが、競プロを始めたいと思う方の少しでも参考になれば幸いです。
直帰率を下げるには？

直帰率の数字を下げることは、目的ではない。それは単なる数字だ。何の意味もない。

真の目的は、エンゲージメントを高め、満足度を高め、ユーザーをより幸せにすることだ。

1
サイトを高速化すると直帰率は下がる

2
対応する検索意図の幅を広げる
画像、詳細、レビューなど他のリソースにリンクできるように

3
競合分析
検索上位を獲得しているページとの違い

4
質問に答える
しっかりと回答をする

5
関連するリンクを、わかりやすい位置につける

6
CTA
Call To Action　行動喚起
Web上のユーザーに行動を喚起させるするためのテキストや画像に対して使われている用語
リンクできる、文字、画像、ボタン

7
逆ピラミッド
興味→詳細→もっと詳しく→購入
フローの割り当てでNULLの時には追加しない

フローの割り当てでNULLにも関わらずテキスト型のコレクション変数に追加していきました。
NULLは勝手に除外してくれると期待したのですが...


```
割り当て: 承認者２を割り当て
{!Authorizer2UserIds} 加算 {!$Record.ApprovalRoute__r.Authorizer2__r.User__c}　<-null
{!Authorizer2UserIds} 加算 {!$Record.ApprovalRoute__r.Authorizer2__r.UserGroup1__c} <-OK
{!Authorizer2UserIds} 加算 {!$Record.ApprovalRoute__r.Authorizer2__r.UserGroup2__c} <-OK
{!Authorizer2UserIds} 加算 {!$Record.ApprovalRoute__r.Authorizer2__r.UserGroup3__c} <- null
{!Authorizer2UserIds} 加算 {!$Record.ApprovalRoute__r.Authorizer2__r.UserGroup4__c} <- null
```

結果
{!Authorizer2UserIds} = "[,005100000094yhOAAQ,005100000094ygWAAQ,,]"

どうも、,005100000094yhOAAQとなっているので、nullと判断しているようですね。

エラーが発生しました:

Probably Limit Exceeded or 0 recipients. Possible invalid email addresses: null, 005100000094ygWAAQ, 005100000094yhOAAQ
爆速でtailscaleのセットアップをする

## 目的
VPN接続をする時、両環境のTORを触れない場合はグローバルIPを持っているマシンが必要となる。今回はグローバルIPを持つマシンを用意せずにVPNを張るために、tailscaleを使用する。

![tailscale.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738475/f0a69f78-2a0e-7ef6-4c35-bf8f2740e728.png)


## Tailscaleのセットアップ

### サイトへアクセス
- サインインか既にアカウントがある場合はログインする。

https://tailscale.com/

- Download Tailscaleへアクセス

https://tailscale.com/download



- 今回はubuntuをtailscaleで接続して、イントラネットへトラフィックを流す予定なので、LINUXを選択

- ubuntu上でこのコマンドを実行するのみ

簡単すぎる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738475/f6216883-c465-5865-31d9-94fe6cefe4bd.png)

## ubuntuでtailscaleを起動
```
tailscale up
```

## ログイン
以下のURLが払い出されるのでログインする
```bash
To authenticate, visit:

        https://login.tailscale.com/a/XXXXXXXX

tailclace upSuccess.
```

## パケットのフォワーディングの許可
```
echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
sudo sysctl -p /etc/sysctl.d/99-tailscale.conf
```


## 経路情報の追加
```bash
tailscale up --advertise-routes=172.24.20.0/24
```

## Machinesへアクセス
待っていると以下サイトにubuntuが追加される

https://login.tailscale.com/admin/machines

## subnetの編集
トラフィックをubuntuが所属しているイントラネット側に流したいので、サブネットの編集をする


1. Edit route settingsをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738475/b2ba9dda-4573-8f58-003a-d72e385429a9.png)

2. サブネット許可
![WS000103.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738475/27fec9ae-0be9-1d1a-bd00-5f5f2a0c66a9.jpeg)

## 確認
ubuntuが所属しているイントラネットの他のマシンに対してpingを実行

```
C:\Users\shoma>ping 172.24.20.20

172.24.20.20 に ping を送信しています 32 バイトのデータ:
172.24.20.20 からの応答: バイト数 =32 時間 =13ms TTL=63
172.24.20.20 からの応答: バイト数 =32 時間 =12ms TTL=63
172.24.20.20 からの応答: バイト数 =32 時間 =11ms TTL=63
172.24.20.20 からの応答: バイト数 =32 時間 =11ms TTL=63

172.24.20.20 の ping 統計:
    パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
    最小 = 11ms、最大 = 13ms、平均 = 11ms
```
hashの練習

hash={key:値}
シンボルを使ったキーの記述方法は、キーの後にコロン:をつけて定義する。

not[]！ not()！！よく混同しちゃうから気をつけよう。

```ruby
puts hash.keys
puts hash.values
```
これを実行した時に

```ruby
春
夏
秋
冬
pink
yellow
brown
black
```
とターミナルに表示されるような変数hashを作成するためのコードをシンボルを使って書く。

こうなる。
```ruby
hash　=　{春:pink,夏:yellow,秋:brown,冬:black}
```
【Flutter】flutter build ipa でビルドしたファイルをApp Store Connectへアップロードする

# ipaファイルを生成する
ターミナルでFlutterプロジェクトへ移動し、以下のコマンドを実行する。
```
flutter build ipa
```

そうすると、build/ios/ipa に *.ipa が生成される。

# App Store Connectへアップロードする
最初にApp StoreからTransporterをインストールする。

![スクリーンショット 2023-06-07 10.20.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727951/033921f9-2889-fee5-7a68-2fd3befb73b8.png)

TransporterにApple IDでログインし、作成したipaファイルをドラッグ&ドロップする、または「Appを追加」でipaファイルを選択する。

![スクリーンショット 2023-06-07 10.25.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727951/7ed08dd1-f086-6472-da5c-6b6530fa52b8.png)

これで、App Store Connectにアップロードされます。
ruby　値に名前つける練習

ゴルフのスコアが１日目１２０、二日目が１００、三日目が８０だった場合のゴルフスコアの平均点をターミナルに出力するプログラムを記す。

出力結果は、 

３日間のゴルフスコアの平均点は、◯点です。
　
というようにしたい。

条件：各日の点数を変数を使って定義。

```ruby
day_1=120
day_2=100
day_3=80

average_score=(day_1+day_2+day_3) / 3

puts "3日間のゴルフスコアの平均点は、#{average_score}点です。"
```

読みやすいコードを書くことを意識しよう。
バックエンドフレームワークにおける画面間のデータ引継ぎ(フラッシュスコープの適用方針整理)

HTTPがステートレス志向であることに起因していますが、サーバサイドでの画面描画を想定したSpringなどのバックエンドフレームワークで画面描画を行う際は、サーバサイドで画面でデータをどのようなスコープで引き継いでいるのかそのデータライフサイクル引継を意識しながら設計・開発する必要があります。フラッシュスコープなるものの存在を知ったので、その使い分けを簡単にまとめてみました。

# 一般的にどのようなスコープが存在するのか？

| スコープ名 | データのライフサイクル | データの参照範囲 | 想定されるユースケース | 備考 |
| --- | --- | --- | --- | --- |
| リクエストスコープ | リクエストの開始から終了まで存続。 | 同一リクエスト内。 | ユーザのアクションに応じた一時的なデータのやり取り。 |  |
| フラッシュスコープ | 現在のリクエストから次のリクエストまで存続。リダイレクト後の最初のリクエストで消去。 | 現在のリクエストから次のリクエストまで。 | リダイレクト先での通知メッセージの表示など。 | SpringではRedirectAttributes経由で取得 |
| ビュースコープ | 特定のビューが表示されている間存続。新たなビューに遷移すると終了。 | 同一ビュー内。 | 同一ページ内のユーザインタラクションに応じたデータ保持。 | ビュースコープは、JavaServer Faces(JSF)などの一部のWebフレームワークに存在 |
| セッションスコープ | ユーザーセッション全体に渡り存続。ユーザーがWebサイトを閉じたり、一定時間活動がないと終了（またはタイムアウト）。 | 同一ユーザーセッション内。 | ログイン情報の保持、ショッピングカートの状態管理など。 | Javaフレームワークでは一般的にHttpSession経由で取得。 |
| アプリケーションスコープ | Webアプリケーションのライフサイクル全体で存続。 | 全ユーザ、全リクエスト。 | サイト全体の設定や共有データの管理。 |  |

# セッションスコープとフラッシュスコープの使い分け方針

**フラッシュスコープの利用:** 

- あるリクエストから別のリクエストへ一時的なデータを引き継ぐ。例えば、リダイレクト後のページでユーザーに表示する情報（成功メッセージ、エラーメッセージ、フォームの入力値等）を引き継ぎたい場合。
- 状態の少ない（stateless）アプリケーション設計に貢献します。セッションデータの使用を減らすことで、アプリケーションのスケーラビリティが向上します。

**セッションスコープの利用:** 
セッションスコープはユーザーセッション全体で有効で、主に以下のようなケースで使用します。

- ユーザーがシステムにログインしている間、ユーザー情報を保存したい場合。
- ショッピングカートのような、ユーザーセッション全体にわたって状態を維持する必要がある機能を提供したい場合。

どちらのスコープを使用するかは、あくまでユースケースによります。

# 少し悩んだ点（本記事を投稿するきっかけ）

- セッションスコープは従前の通り、リダイレクトを前提としたものですが、リダイレクトは伴わないものの次の画面遷移まで持ち続けたいというケースでは内部的にFlashMapを利用することも可能。（ただし低レベルAPIを利用することになるため、将来のバージョンアップなどに追随できなくなる可能性もあり、セッションスコープを使うことに）

```` サンプル.java
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.servlet.FlashMap;
import org.springframework.web.servlet.FlashMapManager;
import org.springframework.web.servlet.support.RequestContextUtils;

public void someMethod() {
    FlashMap flashMap = new FlashMap();
    flashMap.put("businessList", businessList);

    ServletWebRequest servletWebRequest = new ServletWebRequest(request);
    FlashMapManager flashMapManager = RequestContextUtils.getFlashMapManager(request);

    if (flashMapManager != null) {
        flashMapManager.saveOutputFlashMap(flashMap, servletWebRequest);
    }
}
````
なぜnp.arangeを使うべきではないのか

# 環境
numpy version:1.24.3

# numpy arangeの沼
https://numpy.org/doc/stable/reference/generated/numpy.arange.html

arangeのドキュメンテーションも参考に、次のコードがどのような数列を返すと思いますか？

```py
for i in np.arange(3.0, 4.4, 0.1):
    print(i)
```

想像するのは

```
3.0
3.1
3.2
3.3
3.4
3.5
3.6
3.7
3.8
3.9
4.0
4.1
4.2
4.3
```

こんな出力でしょう。しかし、実際に返されるのは次のような出力です。

```
3.0
3.1
3.2
3.3000000000000003
3.4000000000000004
3.5000000000000004
3.6000000000000005
3.7000000000000006
3.8000000000000007
3.900000000000001
4.000000000000001
4.100000000000001
4.200000000000001
4.300000000000001
4.400000000000001
```

そうなんです。arangeに指定した、endの値の4.4を超えます！！
これがarangeの沼です。つまり、丸目誤差のせいで思った挙動をせず不安定な挙動をします。enumerateと一緒に使って日には最悪です。out of rangeが返ってくるわけですから。

https://snowtree-injune.com/2019/07/07/arange-linspace/

こちらにより詳しい解説がありますので、ご参照ください。

# 結論
上記url記事にもある通り、挙動の安定するnp.linspaceやrangeを使うようにしましょう。
Zig 0.10.1から0.11.0-devのオーバーフロー検知について

# [@addWithOverflow](https://ziglang.org/documentation/0.10.1/#addWithOverflow)と[@subWithOverflow](https://ziglang.org/documentation/0.10.1/#subWithOverflow)について

この関数は、オーバーフローやアンダーフローがおきそうな場合に用いる関数である

# 0.10.1
## 定義
``` zig
@addWithOverflow(comptime T: type, a: T, b: T, result: *T) bool
```
addの結果をresultに格納し、判定をreturnのところで確認している
## 使い方
``` zig
var flag: bool = false;
var result: u64 = undefined;
flag = @addWithOverflow(u64, 1, 2, &result);
```

# 0.11.0-dev
## 定義
``` zig
@addWithOverflow(a: anytype, b: anytype) struct { @TypeOf(a, b), u1 }
```
## 使い方
``` zig
var result: struct { u64, u1 } = @addWithOverflow(1, 2);
```
result[0]がaddの結果である。result[1]は0か1が入る。


# 違い
0.10.1と違うところは0.10.1はbool値であるが0.11.0-devはu1であるところである

# さいごに
詳細は[公式ドキュメント](https://ziglang.org/documentation/master/)を確認してください
【RSS】Bloggerの更新情報を表示する


##### これは、Bloggerの更新情報を取得して、HPにブログの最新記事情報を載せた時のお話です。

ある日の出来事…

*:.。..。.:+·ﾟ·✽:.。..。.:+·ﾟ·✽:.。..。.:+·ﾟ·✽:.。..。.:+·ﾟ·*:.。..。.:+

(会・ω・社)　HPに自社ブログの最新情報のせてよ。

(´・ω・`)　御意。

(´・ω・`)　…ぽちぽち💻。

(´・ω・`)つ　できました。


変更前
![HPブログ付ける前.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3445512/8154e916-3821-2d5a-b391-b8996339d9fe.png)

変更後
![ブログ変更前（集中線）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3445512/204f9096-ea63-7e3e-8a03-85afb0542831.jpeg)



(会・ω・社)　・・・なにこれ。
(´・ω・`)　iframe に スマホサイトぶち込みました。

(会👁ω👁社)　・・・。
(´・ω・`)　はい。ごめんなさい。ほんと、ごめんなさい。

*:.。..。.:+·ﾟ·✽:.。..。.:+·ﾟ·✽:.。..。.:+·ﾟ·✽:.。..。.:+·ﾟ·*:.。..。.:+

こんにちは👀
月島ファクトリープログラマー（？）のmotchyと申します👶
冒頭の経緯から、BloggerのRSS情報の取得～表示を行いました。

BloggerのRSS情報を取得するのに便利なライブラリに出会いましたので、今回はそちらのライブラリをご紹介します。

### rss-parser
https://www.npmjs.com/package/rss-parser

[ココ](https://www.npmjs.com/package/rss-parser#web)のとおりに実装するとアラ便利。
タイトル・日付・リンクがとれるとれる。
ひゃっほー(´・ω・`)🎵

ということで、変更後が下記になります。
とってもスッキリしました。


変更前
![ブログ変更前.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3445512/b41e63ac-83c5-1e66-2cee-27fa87370ede.png)


変更後（すっきり）
![ブログ変更後2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3445512/00d9c921-a00e-90e6-da84-3fd7c6c0d627.png)



現在は、新着５件だけ表示するだけなのですが、そのうち「and more」的なおしゃれな英語使って、10件づつ動的にとれるようにできたらいいなと思ってます。

思った以上にお手軽に対応できたので、WEBサイトにブログ埋め込みたいんじゃーな人は、rss-parser是非使ってみてください。


##### 【参考にさせていただいたサイト】
[やっぱりはてなブログを自分のホームページに埋め込みたい](https://t-n-clark.hatenadiary.jp/entry/2019/05/30/113000)
[Blogger用のブログパーツを作成する](https://feed.mikle.com/ja/support/google-blogger-rss/#headline002)
About Routing in Remix v2.

こんにちは。Enabling team の山本です。

2023年6月1回目は、Remix の [Flat Routes](https://github.com/remix-run/remix/discussions/4482) についてです。

Remix については、以前から注目していました。

特に、サーバーサイド JavaScript を用いずに構築できる点に魅力を感じます。学習コストの面で 👍

そして、昨年、Shopify に買収されたことにより、Remix は、しっかりした企業による力強い support を得られる状況になりました 💪

https://shopify.engineering/remix-joins-shopify

今回話をする Routing について、`v2` では、[Flat Routes](https://github.com/remix-run/remix/discussions/4482) を用います。

https://github.com/remix-run/remix/discussions/4482

> Routing is possibly the most important concept to understand in Remix. Everything starts with your routes: the compiler, the initial request, and almost every user interaction afterward.

Remix の「最も重要な概念」である Routing について、学びます。

## TL;DR
- 階層を分ける必要がありません。

## Routing の違い
### v1
```bash
.
├── app
│   ├── entry.client.jsx
│   ├── entry.server.jsx
│   ├── root.jsx
│   ├── routes
│   │   ├── top20          # ここ
│   │   │   ├── index.jsx  # ここ
│   │   │   └── $id.jsx    # ここ
│   │   ├── _index.jsx
│   │   └── top20.jsx
│   ├── style
│   │   ├── article.css
│   │   └── top20.css
│   └── utils
│       └── hackerNews.server.js
├── .eslintrc.js
├── .gitignore
├── package.json
├── package-lock.json
├── public
│   └── favicon.ico
├── README.md
├── remix.config.js
└── tsconfig.json
```

### v2
- このように書き換えることができます。
```bash
.
├── app
│   ├── entry.client.jsx
│   ├── entry.server.jsx
│   ├── root.jsx
│   ├── routes
│   │   ├── _index.jsx
│   │   ├── top20.$id.jsx     # ここ
│   │   ├── top20._index.jsx  # ここ
│   │   └── top20.jsx
│   ├── style
│   │   ├── article.css
│   │   └── top20.css
│   └── utils
│       └── hackerNews.server.js
├── .eslintrc.js
├── .gitignore
├── package.json
├── package-lock.json
├── public
│   └── favicon.ico
├── README.md
├── remix.config.js
└── tsconfig.json
```

![remix-routing.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569971/dc2f0144-76de-78ca-0014-e0655e68efc5.jpeg)

## Summary
Remix の Flat Routes について、書きました。
こういう変化を見ていると技術選択の重要さを感じます。
数ヶ月前の code が使えなくなる可能性もある。
開発言語や Framework の選択を広げれば、いろいろなことができる一方、それをどうやって管理・開発していくのか。
職業として Engineer をやる以上、deploy してからが本当の始まりです。
【JavaScript】コーディング規約を選定した話


※こちらは2019年に弊社ブログで掲載していた内容と同様の内容の記事になります。

初めまして、MtFormです。
今回はVue.jsのプロジェクトのコーディング規約を定めるにあたっていろいろ迷ったお話です。


### コーディング規約とは（ざっくり概念）

プログラムって、同じ動作をする場合でも異なる書き方ができますよね。
例えば、

    let a,b,c;

と書くか、
    
    let a;
    let b;
    let c;
    
と書くか。

このあたりは個人の好みで書き方が分かれてしまうので、複数人でコードを書くとバラバラの記法になって、バグの原因になったりします。
そこで、コードの書き方を統一するためのルールを定めることにしました、これがコーディング規約です。




### メジャーなJSコーディング規約

コーディング規約を1から全部決めるのは大変なので、大手の企業が公開しているコーディング規約を使わせていただきます。（場合によってはカスタマイズします）
今回は３つの候補に絞りました。

JavaScript Standard Style

・2015年に提唱された。ESLintのサブセットである（カスタマイズ済のESLint）
・行末のセミコロン禁止のため、人によっては受け入れられない。
※セミコロンを必須とした「JavaScript Semi-Standard Style」もある。

Google JavaScript Style Guide
・ESLintの候補として表示されるほど標準的なスタイル
・AngularやGWTなどを開発しているGoogle製

Airbnb JavaScript Style Guide
・ESLintで候補として表示されるほど標準的なスタイル
・GitHub上で最も人気のあるスタイル（starが90kで第1位、第2位は22.7k：2019年11月現在）
・オープンな議論を通じてスタイルが決定している。
・スタイルについてパフォーマンスに関するエビデンスがある。



### 選ばれたのはAirbnbでした

どのスタイルガイドもESLint（JSの構文チェッカー）に対応しているのですが、パフォーマンスに対するエビデンスがあるということで、Airbnb JavaScript Style Guide を利用することにしました。

今回のプロジェクトはVue-CLIで作られていたので、導入は次のコマンドでOK
$ yarn add @vue/eslint-config-airbnb -dev
これでESLintの設定がvue.jsとAirbnb JavaScript Style Guideに対応してくれました。

構文チェックは次のコマンド
$ yarn lint --no-fix
試してみると50個くらいエラーが検出されて焦りましたが、--no-fixオプションを外して実行するとlint側で勝手にコードを修正してくれるのでエラーは5個くらいまで減り、
残りも日本語のリファレンスを見ながら修正できました。



### 苦戦したポイント
個人的に引っかかった部分は次の2点。

##### comma-dangle
[（https://mitsuruog.github.io/javascript-style-guide/#commas--dangling）](https://mitsuruog.github.io/javascript-style-guide/#commas--dangling)

配列の末尾には、カンマが必須らしい！
末尾カンマはJSONだとエラーになるから気持ち悪いなあと思いつつリファレンスを読んでみると、
・末尾コンマはbabelが自動的に消してくれる
・gitの差分がきれいになる
とのこと。
確かに、差分はこっちのほうが断然わかりやすい！
スタイルガイドはgit管理の部分まで視野に入ってるんですね。

BAD
    
    const array = [
      apple,
      banana,
      chocolate
    ];

GOOD
    
    const array = [
      apple,
      banana,
      chocolate,
    ];


##### operator-linebreak
[（https://mitsuruog.github.io/javascript-style-guide/#variables--linebreak）](https://mitsuruog.github.io/javascript-style-guide/#variables--linebreak)
代入で=の前後に改行を入れてはいけない。
でも、そこを直したらmax-lenの100文字に引っかかってエラーになるんだけど……。
という板挟みの状況に陥ったわけですが、リファレンスにはちゃんと書いてありました。

そういう場合は、「値を丸括弧で囲むこと」だそうです。

BAD
    
    const text =
      'superLongText';

GOOD
    
    const text = (
      'superLongText'
    );


##### 結論
Airbnb JavaScript Style Guideは、リファレンスが丁寧！！
以上です、ありがとうございました。

##### 参考サイト

・JavaScriptのスタイルガイドまとめ(おすすめ4選)
https://qiita.com/takeharu/items/dee0972e5f39bfd4d7c8
・JavaScript Standard Styleのススメ
https://arui.tech/recommendation-of-standard-js/
・セミコロンは省略？人気スタイルガイドに学ぶJavaScriptのコーディング規則
https://www.webprofessional.jp/why-use-javascript-style-guide/
・JavaScriptの有名なコーディングスタンダードまとめ
https://blog.htmlhifive.com/2017/09/12/javascript-style-guide/
・ESLintをAtomに導入し、Reactの構文にも対応したAirbnbのJSスタイルガイドを使う
https://mae.chab.in/archives/2874
雑談：Nordic Tech Tour

# 久々にセミナー

https://www.nordicsemi.com/Events/2023/Nordic-Tech-Tour-APAC-2023

Nordic Tech Tourに参加してきました。目的としてはお弁当が出る、ただそれだけです(笑)

::: note
いや、間違ってはいない(キリッ
:::

で、お弁当だけだと思っていたら、なんと！！！
コーヒーなどの飲み物や軽食(クッキーやサンドイッチ)まで食べ放題という至れり尽くせりのおもてなし。いったいこのセミナーいくらかけているんだ(場所ヒルトンだし)という感じ。
いや、でもNordicってコロナ前は結構こういうことをしていたんですよね。覚えているのは幕張メッセでの懇親会ですかね。たしかワインなんかも飲み放題だったような記憶がなんとなくあります。
# セミナーの内容は
もうnRF Connect SDK全押しって感じでした。これからはnRF Connect SDKで自社の全てのICをサポートするからみんなこっち使おうぜ！という内容でした(要約です)
雑談も割とあって、代表取締役が「かつてハードウェアはゴミです！とまで言われました」みたいなことを言ったんですよね。最後の質疑応答で「それってもしかして"わ"から始まる人の名言ですか？」と聞こうと思ったのですが大人の対応で止めておきましたwww
## ThreadとMatterも推し
どうもMatter over Threadが次世代のトレンドのようです。
・・・あれ？Threadの対抗馬であるはずのBLE Meshはどこへ？
これも質疑応答で「もしかしてBLE Meshはオワコンですか？」と聞こうと思ったのですが諸般の事情で止めることにしましたw
ということで僕もThreadとMatterを勉強していこうと思います。

::: note
本当に中身のない雑談だなwww
:::
【facebook】Messengerプラットフォーム


※こちらは2019年に弊社ブログで掲載していた内容と同様の内容の記事になります。

ある日の出来事…
*:.。..。.:+·ﾟ·✽:.。..。.:+·ﾟ·✽:.。..。.:+·ﾟ·✽:.。..。.:+·ﾟ·*:.。..。.:+

インスタントゲームを作ったはいいが、ゲームのリテンションが低すぎてつらいよお…あれ、facebookさんがコッチを見ている…(´；ω；`)ｳｯ

(face・ω・book)つ …ｽｯ[「再エンゲージメントのためにゲームボットを設定する」](https://developers.facebook.com/docs/games/build/instant-games/get-started/quick-start?locale=ja_JP)

(´；ω；`)！！

*:.。..。.:+·ﾟ·✽:.。..。.:+·ﾟ·✽:.。..。.:+·ﾟ·✽:.。..。.:+·ﾟ·*:.。..。.:+

こんにちは👀

月島ファクトリープログラマーのmotchyと申します👶

冒頭の経緯から、インスタントゲームでボットを使用したいと考え、facebookのMessengerプラットフォームを使用しました。

今回は、インスタントゲームでMessengerプラットフォームを使用するまでの過程について投稿させていただきます。
以下、3つのステップでご説明します。

1. Facebookページを作成しよう！
1. Webhookを設定しよう！
1. Messengerプラットフォームを使えるように申請しよう！

#### 1.Facebookページを作成しよう！
ゲームボットを使用するには、インスタントゲームと連動するFacebookページが必要になります。なので、まずはゲーム用のページを作成しましょう😃

#### 2.Webhookを設定しよう！
ゲームとFacebookページを連動させることによって、メッセンジャーを使用してメッセージの送受信を行った際、バックエンドにHTTPコールが送信されます。
サーバーのエンドポイントをページのイベントと紐づけるために、Webhookの設定をします。
facebookのチュートリアルは正直わかりにくかったので、わたしは下記サイトを参考にし（て、インフラの方に設定してもらい）ました。
[「Facebook Messengerでチャットボットを作ってみる手順まとめ【保存版】」](https://ledge.ai/facebookbot_exp/)
[「Facebookページのメッセンジャーボットを自作しよう～ボットの設置まで～」](https://kekaku.addisteria.com/wp/20180601192333#Webhooks)

#### 3.Messengerプラットフォームを使えるように申請しよう！
Messengerプラットフォームを使用するには、pages_messagingというSend APIの承認が必要になります。アプリダッシュボードの「Messengerのアプリレビュー」から簡単に申請することができます。

上記の手順を行うと、プレイヤーがインスタントゲームを終了するたびに、「2.Webhookを設定しよう！」で用意したサーバーにPOSTリクエストが飛んできます。
このPOSTリクエストから、プレイヤーにメッセージを送信するためのPSIDを含んだ下記のユーザー情報が取得できます。
[「messaging_game_plays Webhook Event Reference」](https://developers.facebook.com/docs/messenger-platform/reference/webhook-events/messaging_game_plays/)

これでユーザーにゲームやれやれってメッセージを送り放題だ👿👿👿
わーい👿👿👿

…は、facebookさんは許さない。もうひと手間。

設定は3ステップで終了ですが、ボットを受け取るか受け取らないかはユーザー次第です。

2019年1月以降の新規ユーザーについては、ユーザーボットがデフォルトで無効に設定されるようになりました。
そのため、インスタントゲームに、ゲームボットを承認してくれるかユーザーに問う処理を実装してください。
[「Important Game Bots Update」](https://www.facebook.com/fbgaminghome/blog/important-game-bots-update)


#### ★最後に
*:.。..。.:+·ﾟ·✽:.。..。.:+·ﾟ·✽:.。..。.:+·ﾟ·✽:.。..。.:+·ﾟ·*:.。..。.:+

Messengerプラットフォームの対応については、設定のフェーズでかなり時間がかかった印象だったことから今回の投稿内容に至りました。

ただ、思い返して書き起こしてみたはいいものの、そんなに難しいことしてないので、ちょっと悔しいです。（facebookのチュートリアルきらいだ…(´・ω・`)ﾎﾞｿ。）

また何か新しい機能を使用した際には、ブログ更新したいと思います。

以上です。
最後まで読んでいただき、ありがとうございました。

*:.。..。.:+·ﾟ·✽:.。..。.:+·ﾟ·✽:.。..。.:+·ﾟ·✽:.。..。.:+·ﾟ·*:.。..。.:+
pathlibを使って、ファイル名変換プログラムを作ってみた！

　久しぶりのQuiita投稿です。今回はpathlibを使い、ファイル名変換プログラムを作ってみました。

　参考にしたテキストは、この書籍です。
https://www.amazon.co.jp/Python%E3%81%A7%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8%E3%81%99%E3%82%8B%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E5%85%A5%E9%96%80-%E2%80%95%E2%80%95%E3%82%82%E3%81%86%E6%8C%AB%E6%8A%98%E3%81%97%E3%81%AA%E3%81%84%EF%BC%8110%E3%81%AE%E5%A3%81%E3%82%92%E8%B6%8A%E3%81%88%E3%81%A6%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC%E3%81%AB%E3%81%AA%E3%82%8D%E3%81%86-%E7%9F%B3%E4%B8%8A-%E6%99%8B/dp/4297132923/ref=sr_1_27?crid=V74KHVN3WZW3&keywords=python+%E5%85%A5%E9%96%80&qid=1686095523&sprefix=python%2Caps%2C208&sr=8-27

　上記リンクの5章に載っていたプログラムを学習し成果をこちらに投稿いたします。目的としては、下図、"無題1〜10" のテキストファイルを変更したいファイル名に変換することです。一つ一つファイル名を変更していくと膨大な手間がかかりますので、プログラムによる自動化をします。   

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2631873/6917ab9e-832d-400d-302d-adb898e299c8.png)

 では、サンプルプログラムを展開します。とても簡単です。

```py
from pathlib import Path

for i in range(1,11):                        ///1から10までの繰り返し処理
    rename_from = "無題" + str(i) + ".png"   ///変更したいファイル名を指定
    rename_to = "cat-" + str(i) + ".png"     ///変更後のファイル名を記述
    print(rename_from + "を" + rename_to + "に変更します")   ///コマンドに出力
    path = Path(rename_from)                 ///変更前のファイルパスを読み取る
    path.rename(rename_to)                   ///任意のファイル名に変更する
```
コードそのものは上記のように、8行程度で済みます。今回はコマンドから実行し、ファイル名変更の実行結果をコマンドにも表示させるという非常にシンプルな構成となっております。

　それでは、実行してみます。今回はWindows PowerShellからの実行となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2631873/3a127049-26f6-bf45-c7d9-95834b11ac1a.png)
実行結果は以下の通り
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2631873/bf490e55-3727-07cd-5024-e278ccee1f59.png)
コマンド上には"無題1〜10"のファイルが"cat-1〜10"に変更されていると表示されています。では実際に変更されたか否かをフォルダを開いてみてみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2631873/028bb2c3-8c83-1aa6-6ce9-7121ba546d26.png)
ご覧のように、"cat-1〜10"に変更されているのがわかりますね。ファイル名変換プログラムは成功しました。

　私としても、まだまだ勉強中ですので至らない点が多々あるとは思いますが。そこら辺はご容赦ください。こういったファイル変換プログラムは日々の業務でも活かせるプログラムですので、今回投稿させていただきました。次回はエントリーボックスに入力した値をそのままファイル名に変換するプログラムを勉強して作成してみたいと考えています。こういったコードを数多く知り、日々の業務を楽にしていきたいと思います。

エンジニアファーストの会社[株式会社CRE-CO](https://www.cre-co.jp/#top)　H.M
[ローカル環境] faster-whisper を利用してリアルタイム文字起こしに挑戦2

## はじめに

[[ローカル環境] faster-whisper を利用してリアルタイム文字起こしに挑戦](https://qiita.com/reriiasu/items/920227cf604dfb8b7949)の続編になります。


お試しで作ったアプリでは、十分な検証ができるものではなかったため、改善を行いました。
手探りで挑戦しましたので、何かご指摘がありましたらお教えいただければ幸いです。

2023 年 06 月 07 日
2023 年 06 月 18 日 更新

## 画面

![UseAnimation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553528/6b99fa64-1b4a-784e-c625-68952754fe34.gif)

下記にコードを置いています。
https://github.com/reriiasu/speech-to-text

## 改善ポイント

1. [faster-whisper](https://github.com/guillaumekln/faster-whisper)に渡すパラメータを簡単に変更できる状態にない。
1. faster-whisper のパラメータが多く簡単に入力できない。
==> GUIに対応して改善を図る。
1. PyAudio だと ASIO が利用できない。
==> Sounddevice を利用する。


### GUI 

[Eel](https://github.com/python-eel/Eel)を利用して HTML ベースの UI を作成する

> Eel とはシンプルな Electron のようななオフライン HTML/JS GUI アプリを作成するための小さな Python ライブラリ

採用理由：慣れている HTML でいい感じの UI を作ろうと考えた。

## 苦労した点

1. パラメータが多すぎる。

   - テンプレートを作成し、パラメータ情報を元に ChatGPT に依頼して作成しました。
     全件出力するよう依頼しないとすぐ｢他と同じですので同じようにやってください｣と回答され、繰り返し作業の削減の依頼が達成できない状態に陥ります。
   - パラメータを再帰的に取得できるよう HTML/JavaScript を作成
     Eel と JavaScript 間は JSON でやり取り。
     JSON の key とパラメータをマッピングして関数をコール
   - パラメータの意味・設定範囲がわからないパラメータが存在する。
     バリデータの作成ができないので、データ型が合うようにしてそのままパラメータとして渡す方針としました。

## 課題

- ~~設定値の保存とロードができない。~~
対応しました。
- ~~意味のわからないパラメータが存在する。~~
[faster-whisperのパラメータを調べてみました](https://qiita.com/reriiasu/items/5ad8e1a7dbc425de7bb0)
- ~~アプリとしての細かい制御パラメータが外部設定できない。~~
対応しました。


## TODO

- ~~課題の解消~~
解決済み
- ~~Silero VAD を試してみる~~
対応しました。
- フロントエンドとバックエンドに処理が分かれたので、フロントエンドから音声ファイルを送るようなこともできそう。
- フロントエンド側が肥大化するようならフレームワークの導入を検討
現状でも思ったよりコード量が増えてしまった。

### ソースコード

下記にソースコードを置いています。(MIT)
https://github.com/reriiasu/speech-to-text

## 参考

- [faster-whisper](https://github.com/guillaumekln/faster-whisper)
- [Eel](https://github.com/python-eel/Eel)
Swiftで解くAtCoder（ABC292）

# 1.はじめに
この記事では、[AtCoder（ABC292）](https://atcoder.jp/contests/abc292)のA~C問題をACしたコードの公開, 解説を行います。
Swiftを使ってコンテストに参加する方の参考になれば幸いです。

# 2.事前準備
標準入力を読み込むためのメソッドです。
コードの先頭に貼り付けて、適宜使用します。
```Swift
import Foundation

// 標準入力から整数を読み込む
func readInt() -> Int{
    return Int(readLine()!)!
}

// 標準入力から整数列を読み込む
func readInts() -> [Int]{
    return readLine()!.split(separator:  " ").map { Int(String($0))! }
}

// 標準入力から文字列を読み込む
func readString() -> String{
    return readLine()!
}

// 標準入力から文字列配列を読み込む
func readStrings() -> [String]{
    return readLine()!.split(separator:  " ").map { String($0) }
}
```

# 3.A - CAPS LOCK 
問題文や制約は[こちら](https://atcoder.jp/contests/abc292/tasks/abc292_a)からご確認ください。
[AtCoder Problems](https://kenkoooo.com/atcoder/#/table/)によるDifficultyは7になります。
```Swift
let S = readString()
 
print(S.uppercased())
```

# 4.B - Yellow and Red Card
問題文や制約は[こちら](https://atcoder.jp/contests/abc292/tasks/abc292_b)からご確認ください。
[AtCoder Problems](https://kenkoooo.com/atcoder/#/table/)によるDifficultyは39になります。
```Swift
let line1 = readInts()
let N = line1[0]
let Q = line1[1]
var c = [Int]()
var x = [Int]()
for _ in 0..<Q {
    let nextLine = readInts()
    c.append(nextLine[0])
    x.append(nextLine[1])
}

var pointList = [Int]()
for _ in 0..<N {
    pointList.append(0)
}
for i in 0..<Q {
    if c[i] == 1 {
        pointList[x[i]-1] += 1
    } else if c[i] == 2 {
        pointList[x[i]-1] += 2
    } else if c[i] == 3 {
        if pointList[x[i]-1] >= 2 {
            print("Yes")
        } else {
            print("No")
        }
    }
}
```

# 5.C - Four Variables
問題文や制約は[こちら](https://atcoder.jp/contests/abc292/tasks/abc292_c)からご確認ください。
[AtCoder Problems](https://kenkoooo.com/atcoder/#/table/)によるDifficultyは444になります。
```Swift
let N = readInt()

func getDivisorCount(n: Int) -> Int{
    var count = 0
    let sqrtN = Int(sqrt(Double(n)))
    for i in 1...sqrtN {
        if n % i == 0 {
            count += 2
        }
    }
    if sqrtN * sqrtN == n {
        count -= 1
    }
    return count
}
var sum = 0
if N % 2 == 0 {
    for i in 1..<N/2 {
        sum += getDivisorCount(n: i) * getDivisorCount(n: N-i)
    }
    sum = sum * 2
    sum += getDivisorCount(n: N/2) * getDivisorCount(n: N/2)
} else {
    for i in 1...N/2 {
        sum += getDivisorCount(n: i) * getDivisorCount(n: N-i)
    }
    sum = sum * 2

}

print(sum)
```

# 6.さいごに
間違いや改善点等あれば、ご指摘いただけると幸いです。
何卒よろしくお願いいたします。
cscの作法 その349

# 概要
cscの作法、調べてみた。
練習問題、やってみた。

# 練習問題
closedxmlでinsertdataを使った、xlsxを作れ。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/c0edc6ed-2597-87fc-6e0e-a91f1ebce089.png)

# サンプルコード

```


using System;
using System.Text;
using System.IO;
using System.Data;
using System.Data.Common;
using System.Transactions;
using System.Data.SQLite;
using ClosedXML.Excel;

namespace App
{
	class Program {
		static void Main(string[] args) {
			var filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Book15.xlsx");
			var wb = new XLWorkbook();
			var ws = wb.Worksheets.Add("Sheet1");
			int i = 1;
			ws.Cell(i, 1).Value = "Id";
			ws.Cell(i, 2).Value = "Name";
			ws.Cell(i, 3).Value = "Number";
			ws.Cell(i, 4).Value = "Price";
			SQLiteConnectionStringBuilder ConnectionStr = new SQLiteConnectionStringBuilder();
			ConnectionStr.DataSource = "db0.sqlite";
			using (SQLiteConnection Connection = new SQLiteConnection(ConnectionStr.ToString()))
			{
				Connection.Open();
				using(SQLiteCommand Command = new SQLiteCommand(Connection))
				{
					Command.CommandText = "SELECT * FROM fruit ORDER BY id ASC";
					using(SQLiteDataAdapter dataAdapter = new SQLiteDataAdapter(Command))
					{
						DataTable table = new DataTable();
						dataAdapter.Fill(table);
						var rangeWithData = ws.Cell(2, 1).InsertData(table.AsEnumerable());
					}
				}
			}
			wb.SaveAs(filePath);
			Console.WriteLine("ok");
		}
	}
}





```


以上。
DAOにおける意思決定「Snapshot」とは？


### Snapshot とは？

![snapshot_アートボード-1-1-1024x341.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416622/1d108e08-ba4d-90ce-e442-275bb76e6bf3.png)


Snapshot（[Snapshot.org](https://snapshot.org/)）とは、一言でいえば、「ガバナンス・トークンの投票所」です。自分が所有するトークン量に応じて、投票を行うことができます。この後の運用例でも詳しく取り上げますが、直近では「山古志村のデジタル村民」の意思決定として、投票が行われていました。

DAOに属していない方には、なかなか聞きなれない言葉かもしれませんが、`ENS`や`Decentraland` `Uniswap`などの超がつくほどの有名プロジェクトやサービスにおける意思決定でも採用されています。

![スクリーンショット-2022-06-17-22.53.21-1024x595.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416622/fd0e160c-a197-15c3-af49-4ec6227c71a4.jpeg)


***

### ガバナンス・トークン とは？

「ガバナンス・トークン」とは、簡単に言うと…中央集権ではないDAOなどの意思決定には必須の「投票権がついた株式」です。この「ガバナンス・トークン」の保有者は、自分が保有するトークン量＝票数として、意思決定に参加することができます。

DAOには中央集権的に意思決定を行う人物がいないため、例えば「次は、Aという行動を取るべきか、Bという行動を取るべきか、どちらがいいですか？」といった提案に対して、「ガバナンス・トークン」を持つ人は、どちらの行動が良いか投票を行います。基本的には、`トークン1つ＝1票`として扱われます。

DAOによっては、投票権としてだけでなく、提案を起案するための権利のような使い方もできます。

:::note info
ガバナンス・トークンの例
- NinjaDAO ： $CNGT（活躍や貢献に応じて配布）
- ENS： $ENS（運営をDAO化した際にAirDropで配布）
:::

「ガバナンス・トークン」の入手方法はプロジェクトやDAOによって様々ですが、中には分散型取引所でのスワップによって入手できるものもあります。

### DAOにおけるガバナンストークンの運用例

![山古志_アートボード-1-1024x341.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416622/5df7b844-13c5-710a-380d-289113b58d99.jpeg)


山古志村が発行する「Colored Carp」「NISHIKIGOI」は、山古志村のデジタル村民であることを示す「デジタル住民票」も兼ねるNFTコレクションです（リアルな住民票やマイナンバーとの連携はありません。あくまで、デジタルの世界での住民票です）。

Discrodのコミュニティでは、デジタル住民が考える山古志村のための「事業プラン」 を募集していました。集まった事業プランのうち、デジタル住民の投票によって選ばれた事業プランに対して、NFTの売上から活動予算を充てる…という流れです。「第一回 山古志デジタル村民総選挙」では、12件の事業プランの中から、実際に予算をつけて活動していく4件を選定するために、Snapshotが使用されています。ここでは、保有するNFTが投票権として機能しました。

![1500x500.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416622/37a45ae8-4ee2-f743-c2b7-6a3a2a53ff9b.jpeg)


この「山古志デジタル村民総選挙」で選ばれたプロジェクトの1つには、「NFTを買い集めて村の財産作り」という事業があります。山古志村の共有財産としてNFTを保有し、山古志村のために活用しよう！…というプロジェクトです。

ここでは、具体的にどのNFTを購入するのがよいか、候補となる9つのNFTプロジェクトの中から、デジタル住民の投票で決定しました。もちろん、投票にはSnapshotが使用されており、「NISHIKIGOI」NFTが投票権として機能しました。

>少し本筋とは離れますが、候補として選定された9つのNFTプロジェクトを分析したシートは、ぜひ見ておいた方が良いです。それぞれのNFTコレクションの特徴と、それらを山古志村が持つ意義をまとめたシートは、「運営体がNFTを保有する際に、どんな点を考慮して選ぶのか」といった目線を知ることができて、とても勉強になります。
※山古志村 NFT購入候補リスト（[コチラ](https://docs.google.com/spreadsheets/d/1ie1FdtZDoZF6VQ92YjMKhvXl_iSU3cSqgGV2NSFpIIk/edit#gid=0)から、Googleスプレッドシートが開きます）


この記事は、著者が運営するメディア「ぬるぺでぃあ」でも読むことができます（記事は[コチラ](https://miuradonuts.com/2023/06/18/nft-note001/)）
![](https://miuradonuts.com/wp-content/uploads/2023/06/ヘッダーエリア画像作成.png)
文字のアニメーションどれにしますか？ってときに見せるやつ

タイトルどおり文字のアニメーションどれにしますか？ってときに見せるやつ。毎回そんなに変わるわけではないので、実用的なものを一覧で。こんなの書いててあれですが、文字の動きは基本的に不要だと思っているので、穏やかに行きませんか？を合言葉に静かなサイトを作っていきたい。さよならパララックス！（流れ弾）

<p class="codepen" data-height="320" data-default-tab="result" data-slug-hash="bGmXZeK" data-user="nishinoshake" style="height: 320px; 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/nishinoshake/pen/bGmXZeK">
  Text Animations</a> by nishinoshake (<a href="https://codepen.io/nishinoshake">@nishinoshake</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## 使い方
[CodePen](https://codepen.io/nishinoshake/pen/bGmXZeK) で .anime のHTMLをコピペ、該当するクラス名のCSSをコピペ、JSで is-active クラスを追加、で動きます。イージングはCSS変数で定義しているので忘れずにコピペしてください。

```html
<p class="anime anime-fade-y">Guardians of the Galaxy</p>

<style>
:root {
  --ease-relaxed: cubic-bezier(0.28, 0.11, 0.02, 1);
}

/* anime-fade-y */
.anime-fade-y {
  opacity: 0;
  transform: translateY(0.5em);
}
.anime-fade-y.is-active {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 400ms ease, transform 640ms var(--ease-relaxed);
}
</style>

<script>
setTimeout(() => {
  document.querySelector('.anime').classList.add('is-active')
}, 500)
</script>
```

## 小技
文字を分割するときにCSS変数でインデックスを振ると便利。[web.dev](https://web.dev/building-split-text-animations/) に素敵な記事があったので貼っておきます。↓のコードも大部分は記事を参考にしています。`<span>` で分割される文字が可愛そうだと思わないのか！さよならパララックス！（流れ弾）

* [Building split text animations](https://web.dev/building-split-text-animations/)

```js
const splitText = (el) => {
  if (el.firstChild === null || el.textContent === null) {
    return
  }

  const characters = el.textContent.split('').map((character, index) => {
    const span = document.createElement('span')

    span.textContent = character
    span.style.setProperty('--index', index.toString())

    return span
  })

  el.firstChild.replaceWith(...characters)
}

const target = document.querySelector('.target')

if (target) {
  splitText(target)
}
```
「ユーザインターフェースログインの多要素認証」権限の一括変更


+ [Sandboxを作成、リフレッシュしたときに一括で、プロファイルの「ユーザインターフェースログインの多要素認証」のチェックを外したい](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000Pf5ch)


:::note
システム権限 ＞除外ユーザの多要素認証を放棄 を有効化した権限セットを作って、この権限セットを以下の方法で一括割り当てする方法もあると思います。
https://sf.forum.circlace.com/articles/782615326377381888


データローダを使用して権限セットを一括で割り当てる
https://help.salesforce.com/s/articleView?id=000384595&type=1
:::

以下に興味深い情報

プロファイルのシステム権限関係はProfileオブジェクトではなく、PermissionSetオブジェクトで管理されています。

エクスポートは出来たのですが、PermissionSetオブジェクトに対し、Updateしようとしたところ「You can’t create, edit, or delete this permission set because it's associated with a profile.」というエラーが出てしまいました…
ラズパイ ＋ ffmpeg で Web カメラ映像をH.264コーデックで保存する方法

すぐに忘れてしまうので。

## コマンド

映像のみで音声無し、ハードウェアエンコードを使用する場合。

```bash
ffmpeg -s 640x480 -r 15 -i /dev/video0 -b:v 1000k -c:v h264_v4l2m2m -pix_fmt yuv420p video.avi
```

`-s`: 解像度
`-r`: FPS
`-b:v`: ビットレート

コマンド実行すると録画が始まり、キーボードの`Q`キー押下で録画終了となる。

## メモ

ラズパイに接続されているカメラは次のコマンドで確認できる。
- `v4l2-ctl --list-devices`

接続しているカメラの解像度やFPS、対応コーデックなどは次のコマンドで確認できる。

- `v4l2-ctl -d /dev/video0 --list-formats`
- `v4l2-ctl -d /dev/video0 --list-formats-ext`
- `ffmpeg -hide_banner -f v4l2 -list_formats all -i /dev/video0`

`mediainfo` コマンドを使用すれば、動画ファイルの解像度やFPS,ビットレート,コーデック,動画の長さ（尺）などが確認できる。
※コマンドが使えない場合は `sudo apt-get install mediainfo` でインストールできる。
- `mediainfo video.avi`

## 参考サイト

- [Raspberry Pi: 動画の撮影](https://hazm.at/mox/gadget/raspberrypi/camera/movie/index.html)
DevOps Center コミットの停止が発生した場合のトラブルシューティング

[DevOps Center まとめに戻る](https://qiita.com/Keiji_otsubo/items/3969e9a6c09cf727a4d9)


+ [Stalled Commit](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000QMIcL)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/e7a84bb0-b4ab-a3b4-881b-18905e2aaf19.png)

:::note
If you encounter a stalled commit, I have written some troubleshooting content. I hope it's helpful and encourage feedback either way.

https://help.salesforce.com/s/articleView?id=sf.devops_center_commit_stalled.htm&type=5
:::


+ [Help : Stalled Commits](https://help.salesforce.com/s/articleView?id=sf.devops_center_commit_stalled.htm&type=5)