OmniAICreator/Qiita-1.07M huggingface dataset:
[Flutter] 端末の情報を取得する方法

今回は、端末の情報を取得してテキストの表示する方法をご紹介します。


使うパッケージはこちら

https://pub.dev/packages/apple_product_name

このパッケージですが、下のパッケージの少し上位互換です。（私の感想です。）

https://pub.dev/packages/device_info_plus



では、実装していくうぅぅ


#①apple_product_nameを入れる

使いたいプロジェクト内のターミナルにコマンドを打ちます。

```dart
flutter pub add apple_product_name
```

注意）pubspec.yamlに直接記入してもOK!

コマンドを入力すると、pubspec.yamlも追加されます。

```dart
dependencies:
  apple_product_name: 
```

次に、`pub get`をしましよう。


# ②実際に使ってみよう

とりあえず、必要そうな情報を並べたサンプルアプリを作ってみました。

```dart
import 'package:apple_product_name/apple_product_name.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: const HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  String infoName = '';
  String infoModel = '';
  String infoSystemName = '';
  String infoSystemVersion = '';
  String infoMachine = '';

  @override
  void initState() {
    super.initState();
    checkAppProductName();
  }

  void checkAppProductName() async {
    final info = await DeviceInfoPlugin().iosInfo;
    var infoMachines = AppleProductName().lookup(info.utsname.machine!);
    setState(() {
      infoName = info.name!;
      infoModel = info.model!;
      infoSystemName = info.systemName!;
      infoSystemVersion = info.systemVersion!;
      infoMachine = infoMachines;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          Text(infoName),
          Text(infoModel),
          Text(infoSystemName),
          Text(infoSystemVersion),
          Text(infoMachine),
        ],
      ),
    );
  }
}

```

画面がこんな感じです。

![Simulator Screen Shot - iPhone 8 Plus - 2022-01-31 at 13.35.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/76ea080d-0efd-8864-5820-5cfa29242999.png)


# ③説明


ゆっくり説明していきます。
私の解釈で説明していくので、間違っていたら指摘してもらえると、勉強になります。

まず初めに、使えるようにするために、定義づけをします。
俗に言う、インスタンス化します。


```dart
final info = await DeviceInfoPlugin().iosInfo;
```


これより、使えるようになります。

```dart
//名前　　→ 「iPhone 8」とか自分でつけた名前など
info.name!
```

```dart
//iOSかAndroidの判断
info.model!
```


```dart
//端末　→ 「iPhone」とか
info.systemName!
```


```dart
//システムバージョン -> iOS 15.1とか
info.systemVersion!
```


一つだけ、癖があるものがあります。それを使えるようにするために、`apple_product_name`を使います。



```dart

//「iPhone10,1」 とかよくわからないものが出てくる。　→ これを変換する必要がある。
info.utsname.machine!


//機種名　→ 「iPhone 8」とか自分の端末の名前になる。
AppleProductName().lookup(info.utsname.machine!)
```










開発する上で、役に立てればいいなと！！
SQLSTATE[HY000] [2002] Connection refused が出た時の対処方法

###エラー内容

このような内容でした

```terminal
SQLSTATE[HY000] [2002] Connection refused (SQL: select * from information_schema.tables where table_schema = laravel and table_name = migrations and table_type = 'BASE TABLE')

  at vendor/laravel/framework/src/Illuminate/Database/Connection.php:712
    708▕         // If an exception occurs when attempting to run a query, we'll format the error
    709▕         // message to include the bindings with SQL, which will make this exception a
    710▕         // lot more helpful to the developer instead of just the database's errors.
    711▕         catch (Exception $e) {
  ➜ 712▕             throw new QueryException(
    713▕                 $query, $this->prepareBindings($bindings), $e
    714▕             );
    715▕         }
    716▕     }

      +36 vendor frames 
  37  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))

```

###対処法

```php artisan tinker```で.envファイルの内容がちゃんと反映されてるか確かて見たところ、反映されていなかったためこれが原因だったようです。

```terminal
root@8dae87ded68a:/var/www/app# php artisan tinker
Psy Shell v0.11.1 (PHP 8.0.15 — cli) by Justin Hileman
>>> config('database')
=> [
    ../
       "mysql" => [
         "driver" => "mysql",
         "url" => null,
         "host" => "127.0.0.1",　#要注意
         "port" => "3306",
         "database" => "laravel",＃要注意
         "username" => "root",#要注意
         "password" => "",#要注意
         "unix_socket" => "",
         "charset" => "utf8mb4",
         "collation" => "utf8mb4_unicode_ci",
         "prefix" => "",
         "prefix_indexes" => true,
         "strict" => true,
         "engine" => null,
         "options" => [],
       ],
../
```

なので.envファイルを適用させればいいのですが、```php artisan config:clear```コマンドで内容を適用させればいらしいんですが、私の場合これではうまく適用されず```rm app/.env```でファイルを削除させもう一度復元させたら成功しました。

###まとめ
ファイルを消さないと適用されないところを治したい
うわっ…私のgitflow、古すぎ…？

# プロローグ

「アジャイルでやってます」っていう現場にジョインしたら単になにもルールを設けず適当にやっていて[1]、gitflowでやろうよって言う前に手順を確認しようと検索してみた。そしたら検索トップに引っかかったのがJiraで有名なAtlassianで、「Gitflowはレガシーだけど歴史的な理由で紹介するね」と書いてあった。

https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow

[1]: 運用ドキュメントには`git add` `git push`などの実コマンドが数行書いてあるだけだった。

## 用語

開発の中心となるブランチ、Subversion時代はtrunk、gitではmasterが主流だったけど、ポリコレの関係でgithub/gitlabともにmaster->mainになったのでこの記事ではmainを使います。

## トランクベースワークフロー

じゃあ今のトレンドはなんなのかというと[トランクベースワークフロー](https://www.atlassian.com/continuous-delivery/continuous-integration/trunk-based-development)らしい。でもこれってCI/CDがちゃんと整っていて、マージされる度にテストが走って、日に数回デプロイするような環境ならともかく、メンバーには新人もいてコードレビューしてからマージしたいような通常の開発では厳しすぎない？

Google Cloud アーキテクチャセンターにはもっと丁寧な説明があった。

https://cloud.google.com/architecture/devops/devops-tech-trunk-based-development?hl=ja

改善方法なども書いてあって「トランクベースならうまく回る」っていうよりも「トランクベースで回す努力しよう」みたいな感じに見える。っていうかこれって[モノレポ](https://en.wikipedia.org/wiki/Monorepo)だとビルドに時間かかるし、いつでも適用できる手法じゃないよね。っていうかatlassianのはポジショントーク的なblog postって感じだし。

## GitHub Flow

そういえばGithub flowってあったよね、っと思って確認するとmainブランチと修正用のブランチしかなくて、形式的にはトランクベースとかわらなさそう。ただトランクベースはポリシー的にもっと誰でもmainにマージできるイメージなのかな。

https://atmarkit.itmedia.co.jp/ait/articles/1708/01/news015.html

# git flow

だいたいみんなが知ってるやつ。developブランチを中心に機能追加はfeature/xxxを作ってレビューしてdevelopにマージ、リリース様にrelaseブランチにマージしてテストが終わったらmainにマージする。バグ修正はhotfixブランチを切って直接mainにもdevelopにもマージできる。

これちゃんとやると結構面倒なので、developを中心に機能別にfeatureを切って、リリース時はmainにマージしてリリースしたらreleaseタグだけ打つ(releaseブランチは切らない)、hotfixはgit flowに準拠してもいいし、急ぎでないならfeatureの一つとして扱って次のリリース時マージに対応、みたいなのが楽でいい。

# Draft (WIP)

今までWIPっていた手法がある。。gitlabでは`WIP:`とついていればマージできず、かつ`WIP:`のON/OFFトグルボタンまであったのだが、久々に行ったら`WIP:`の代わりに`Draft:`を使うことになっていた。一応議論もあった。
https://forum.gitlab.com/t/why-the-change-from-the-wip-merge-request-prefix-to-draft/40239

でも単にGitHubに合わせたんだろう。
https://github.blog/jp/2019-02-19-introducing-draft-pull-requests/

GitHubのプルリク(pull request)はGitLabではマジリク(merge request)になる。でもこういうのは開発プロセスの用語として統一して欲しい。開発してて「WIPでプルリクだしといて」と言えばマージ前レビュー用と作業中タスク管理の意味で使えていたのに、Draftだと広い意味で下書きになってしまうじゃないか。まあそのうち慣れるか。

用語はともかくこれはなにかというと、プルリクの頭に`Draft:`とついていればこれはまだマージ待ち状態じゃないですよ、という印だ。ならプルリクを作らなければいいじゃないかと思うかもしれないが、実際には機能完成前にレビューしてほしい事は結構ある。また、スクラムでやってて「じゃあこのタスクは俺が担当ね」となった時に`Draft:`でプルリク作ってしまえば他のメンバーも進捗が把握しやすい。たまにこれをやるにはgitで空コミットを許可しないと、という話になることがあるけど、別に修正箇所にコメント一箇所だけいれたり空行削除してコミットしてもいいので、空コミット許可は必須ではない。ちゃんとコミットコメント管理するチームならrebaseでコミットまとめたりするだろうし。

# まとめ

てなわけでgit-flow省力版 + Draft運用にする。チームへの周知用ドキュメントにするつもりで書き始めたけど脱線が多いので書き直しだなこれは。

`git develop draft flow`とでも呼ぶかな。誰か粋な名前つけてくれるといいけど
ユーザインターフェース API


# サンプルアプリケーションのインストール

2.Record Viewer Git リポジトリをコピーします。

コマンドプロンプトから

```
git clone https://github.com/forcedotcom/RecordViewer.git
```


あかん、32ビットマシーンにDockerがインストールできない。インストールする方法を見つけたけど、やる気がでない。

[32bit Windows マシンに Docker CE をインストールする](https://waman.hatenablog.com/entry/2018/03/02/231305)


# 利用例

+ [お気に入り登録機能をVisualforceで実装したい](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007bKwVi)

:::note
ユーザインタフェースAPIを使えばできそうです。

As of the Winter '18 release you can now use the User Interface API to get a user's favorites, create a favorite, update a favorite, or delete a favorite. Here is a link to the documentation.

For example, you can create a favorite by making a POST request to the /ui-api/favorites endpoint with this json as the body to favorite a list view:

```Json
{
  name: "Most Important Accounts",
  sortOrder: 1
  target: "00BR0000000tTTwMAM",
  targetType: "ListView"
}
```

https://salesforce.stackexchange.com/questions/186383/add-to-remove-from-lightning-favourites-using-apex-or-the-apis
:::
AWS CLIの振り返り ~Route53入門編~

#本記事の目的
JAWS-UG CLI オンラインハンズオンの復習として、ハンズオンで取り上げられたAWSサービスに関する用語と、使用したAWS CLI コマンドを箇条書きでまとめる。
今回はRoute 53入門編を取り上げる。

#主なAWSサービス用語
####委任セット
同一のAWSアカウントで作成される、4つの権威DNSサーバのセット。
複数のホストゾーンで再利用する事ができる。

####Whois
IPアドレスやドメイン名の登録情報を、インターネットユーザーが参照できるサービス。

####ホストゾーン
ドメイン及びサブドメインのトラフィックのルーティング方法についての情報を保持するコンテナ。

####リソースレコード
DNSにおける、ホスト名やドメイン名の設定が定義されているデータ。
JSON形式のリソースレコード設定ファイルをホストゾーンに対して適用する事で、リソースレコードを作成・更新・削除できる。

####Aレコード
IPｖ4でホスト名とIPアドレスの関連づけを定義するリソースレコードの一種。

####CNAMEレコード
正規ホスト名に対する別名を定義するリソースレコードの一種。

####MXレコード
対象ドメイン宛のメールサーバのホスト名を定義するリソースレコードの一種。

####NSレコード
ゾーン情報を管理するネームサーバーのホスト名を定義するリソースレコードの一種。

####TTL
DNSにおいて、リソースレコードをキャッシュに保持してもよい時間(秒数単位)。


#主なAWS CLI コマンド一覧
####Route53委任セットの作成
```
aws route53 create-reusable-delegation-set \
  --caller-reference ${ROUTE53_REUSABLE_DELEGATION_SET_CALLER}
```
|オプション|引数|必須/任意|備考|
|---|---|---|---|
|--caller-reference|委任セット識別子|必須||

####Route53委任セットの一覧表示
```
aws route53 list-reusable-delegation-sets
```

####Route53委任セットの削除
```
aws route53 delete-reusable-delegation-set \
  --id ${ROUTE53_REUSABLE_DELEGATION_SET_ID}
```
|オプション|引数|必須/任意|備考|
|---|---|---|---|
|--id|委任セットID|必須||

####Route53ホストゾーンの作成
```
aws route53 create-hosted-zone \
  --name ${ROUTE53_HOSTED_ZONE_NAME} \
  --caller-reference ${ROUTE53_HOSTED_ZONE_CALLER} \
  --hosted-zone-config Comment="${ROUTE53_HOSTED_ZONE_COMMENT}" \
  --delegation-set-id ${ROUTE53_REUSABLE_DELEGATION_SET_ID}
```
|オプション|引数|必須/任意|備考|
|---|---|---|---|
|--name|ホストゾーン名|必須||
|--caller-reference|ホストゾーン識別子|必須||
|--hosted-zone-config|ホストゾーンコメント|任意|`Comment="<コメント内容>"`を指定する事で、ホストゾーンに特定のコメントを付与できる。|
|--delegation-set-id|委任セットID|任意||

####Route53ホストゾーンの一覧表示
```
$ aws route53 list-hosted-zones
```

####Route53ホストゾーンの削除
```
aws route53 delete-hosted-zone \
  --id ${ROUTE53_HOSTED_ZONE_ID}
```
|オプション|引数|必須/任意|備考|
|---|---|---|---|
|--id|ホストゾーンID|必須||

####Route53リソースレコードセットの変更
```
aws route53 change-resource-record-sets \
  --hosted-zone-id ${ROUTE53_HOSTED_ZONE_ID} \
  --change-batch file://${FILE_ROUTE53_RESOURCE_RECORD_SET_DOC}
```
|オプション|引数|必須/任意|備考|
|---|---|---|---|
|--hosted-zone-id|ホストゾーンID|必須||
|--change-batch|file://<リソースレコードセット設定ファイルパス>|必須||

####Route53リソースレコードセットの変更状況取得
```
aws route53 get-change \
  --id ${ROUTE53_CHANGE_ID}
```
|オプション|引数|必須/任意|備考|
|---|---|---|---|
|--id|リソースレコードセット変更ID|必須||

####Route53リソースレコードセットの一覧表示
```
aws route53 list-resource-record-sets \
  --hosted-zone-id ${ROUTE53_HOSTED_ZONE_ID}
```
|オプション|引数|必須/任意|備考|
|---|---|---|---|
|--hosted-zone-id|ホストゾーンID|必須||

####

#参考文献
- AWSCLIコマンドリファレンス:[Route53](https://docs.aws.amazon.com/cli/latest/reference/route53/index.html)
- JAWS-UG CLI専門支部：[ハンズオン(簡易版): Route53入門](http://prototype-handson-cli.s3-website-ap-northeast-1.amazonaws.com/handson_light-aws_service/handson_light-aws_service-route53-novice/index.html)
論文まとめ：A Proposal for Multimodal Emotion Recognition Using Aural Transformers and Action Units on RAVDESS Dataset

# はじめに
MDPIのapplied sciencesというジャーナルから以下の論文
[1] C. Luna-Jimenez, et. al. "A Proposal for Multimodal Emotion Recognition Using Aural Transformers and Action Units on RAVDESS Dataset"
のまとめ

- 論文:
https://www.mdpi.com/2076-3417/12/1/327

- コード:
https://github.com/cristinalunaj/MMEmotionRecognition

- SOTAサイトのランキング:
https://paperswithcode.com/sota/speech-emotion-recognition-on-ravdess
こちらで見つけた

以下ではモデル構造などを簡潔にまとめ。

# 概要
- 音声と画像からの感情推定を行うモデル
- ベースのアーキテクチャとして事前学習した xlsr-Wav2Vec2.0 を用いる
- RAVDESS datasetでSOTAを達成した

# 手法
モデルの全体像は以下。

![スクリーンショット 2022-01-31 12.47.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/e716391b-e560-06e1-e951-cd071fe9c663.png)

左上が音声から、特徴量を抽出する部分。左下が動画から特徴量を抽出する部分。右はこれらを用いて感情を推定する部分。

## speech emotion recognizer
音声から特徴量を抽出する部分では、まず事前学習した wav2vec モデルを用いる。特にこちらの
https://github.com/pytorch/fairseq/tree/main/examples/wav2vec#wav2vec-20
53言語で学習された XLSR-53 を用いる。

これに対し、以下の図のように

![スクリーンショット 2022-01-31 12.47.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/9251cc36-fb0d-1964-0c93-91d92a89117e.png)

新たにMLPを加え、各感情の確立を出力する。



## Facial Emotion Recognizer

動画から特徴量を抽出する部分では、まずOpenFaceを用いて前処理し、それを以下のような

![スクリーンショット 2022-01-31 13.06.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/6d4af897-c90d-aed0-ecbf-99e3460f6203.png)

bidirectional-LSTMとattentionを組み合わせたものに入力する。

## multimodal recognizer
音声、および動画から求めたそれぞれの特徴量をconcatし、それをロジスティック回帰で学習する。これで各感情の確立を推定する。
C++におけるデストラクタのvirtual化について

C++ではデストラクタにvirtualをつけておかないとメモリリークするケースがある。下記のように基底クラスと派生クラスでそれぞれコンストラクタでメモリ確保、デストラクタで解放しているとする。

```cpp
class Base {
  private:
    A a;
  public:
    Base(){ a = new A();}
    ~Base(){ delete a; }  // ...1
}
class Child: Base { // Baseを継承してChildを定義
  private:
    B b;
  public:
    Child(){ b = new B(); }
    ~Child(){ delete b;}
}
```
Child型でdeleteすれば問題ない。

```cpp
Child child = new Child();
delete child; ... OK!
```

ポリモーフィズムでBase型にChild型のインスタンスを入れることはよくあるのだが、これが問題になる。

```cpp
Base base = new Child(); // あるいはFactoryからもらってくる
delete base; ... Memory Leak!!!!
```

この場合`delete base`はコンパイル時にBaseクラスのデストラクタに静的に紐付いてしまい、`~Base()`のみが実行される。Childの方はデストラクタが呼ばれずbのメモリを確保したままbaseへのアクセス方法を失う。Baseクラス定義の...1の部分を`virtual ~Base()`としていると、`delete base`の呼び出し時に動的に`base`の現在のbaseクラスのインスタンスをチェックし、`~Child()`が呼ばれてから`~Base()`が実行されるので大丈夫である。わずかなメモリリークは単体・結合テストをすり抜けてしまう。今ではググればすぐわかる事だが、ネットがない時代ではきっと各社で同じ様なバグをだしては各々解決策を探すということをしていたと思う。このあとメモリカウンタ(newとdeleteの回数、呼び出した場所の集計）とか[GC](https://ja.wikipedia.org/wiki/ガベージコレクション)を持った言語の登場などで楽になっていくが、当時はみんな苦労していたのである。

ちなみに、デストラクタの件ではないが筆者も新人の頃に品質管理部門でのエージングテストで一週間後にメモリ逼迫して動作が遅くなるバグを出してしまい、始末書を書いたことがある。そこでは結合テスト以降にバグが見つかった場合は常に始末書だった。

[^6]: 昔のCでは"/* ... */"しか使えなかった



このような時代背景の中でJavaは誕生した。Javaでは多重継承をなくしひし形軽症問題を解決し、機能継承は１クラスに限り可能とし、interfaceだけ複数継承可能とする(後に変更)ことで設計の綺麗さを保とうとした。複数の機能をも継承する場合はそもそも「ドメインモデルの設計自体が悪いのでは？」ということである。これは関数型言語が見直されて型クラスの有用さが認知され、「悪いのは実装を複数継承できることではなく、設計の問題」ということでinterfaceにデフォルト実装がついて型クラスもどきを実装できるようになった。

C++が流行りだした90年代、時代を席巻していたのはC言語だ。関数呼び出しオーバーヘッド一つでも削減したい。そんな思いからデフォルトではvirtualとならず、必要な箇所だけ自分でvirtual宣言する仕様となったのは良い。でも業務でチーム開発する場合は、「デストラクタには常にvirtualをつける」という運用ルールでいいのではなかろうか


```cpp
class Base {
  private:
    A a;
  public:
    Base(){ a = new A();}
    virtual ~Base(){ delete a; }  // ...1
}
class Child: Base { // Baseを継承してChildを定義
  private:
    B b;
  public:
    Child(){ b = new B(); }
    virtual ~Child(){ delete b;}
}
```

え？今更cppを選択するくらいならRustを使う？そりゃそうでしょう。でも世の中には古いソースをメンテし続ける環境もあるのです。

というかC++なんて何十年も書いてないのになんでこんな記事書いたんだろ。下書きにあったから供養のために公開しました。
カメラで写した業務用端末の情報を素早く教えてくれるAI（機械学習）のプロトタイプ

##小売業の困りごと「あるある」

皆様、こんにちは。小売業のシステム部門で働いているhousakoです。
今日は、画像を使った機械学習（AI）で業務端末の区別を行う仕組みを試作してみましたので紹介します。

###ボタンがあるやつ？スマホみたいなやつ？

「なんか発注機の調子が悪いんだけど、どうしたらいいですか？」といった電話は頻繁にありますが、「型番がxx-xxxxという業務端末1台だけ、電源ON後の初期メニューが表示されません。」といったように、内容が具体的なことは極めて稀です。

そのため、大抵ここから「○○の発注に使う端末ですか？」「数字のボタンがついている端末ですか？」といった絞り込みに移るのですが、ハードウェアは生産終了にともなう後継機への移行のため複数の型番が混在するほか、社内システムのデバイスフリー化が進んでいて業務で利用端末が絞り込めないことも相まって、結構な時間を消費します。早く答えが欲しい店舗の担当者にとっては、苦痛な時間です。

そこで、調子が悪い機器をスマホやタブレットのカメラ（パソコンでも可）で映すだけで、瞬時に型番や保守の有無を表示するツールを試作してみました。

###解決のために使うもの

・Windows-PC
・TeachableMachine
・codepen
・カメラ付きデバイス（PC/スマートフォン/タブレット）

###実装手順

まず、TeachableMachineに画像を機械学習させます。
今回学習させるのは、Sharp製の業務用端末3種類です。

・RZ-1502A
・RZ-F302C
・RZ-H261

画像を識別させるにあたり、単一色で無地の背景になることは稀であるため、背景なし、人物や不要物の映り込み、といったノイズを「その他」として覚えこませたのが工夫したポイントです。図の「ニコニコマーク」には人物の顔が映りこんでいますので、加工しています。。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2496293/2543dd7e-2301-f8d2-cdcf-f7db2f5b92f4.png)

機械学習が済んだら、codepenでWEBサイトを用意します。コードは下記の通りです。


<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="eYeppez" data-user="housako" 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/housako/pen/eYeppez">
  店舗機器照会</a> by housako (<a href="https://codepen.io/housako">@housako</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

codepenは色々な画面レイアウトが用意されており、「Full Page View」を選択すればスマホやタブレットで公開できる画面になります。コードを編集しているときに使う画面と、「Full Page View」ではURLが変わるため注意が必要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2496293/ce360e62-de8c-f747-7840-5e580a283012.png)


今回は動画をアップしたかったので、iPadを使って検証しました。（Androidはバージョン11以降でないと、画面キャプチャを動画で取れないようです。。。）
ただ、iPadを使って画面を動画でキャプチャするとMP4ファイルが生成されるのですが、Qiitaにはこの形式で貼り付けることが出来なさそうなので、gifに変換しています。最大画質にしていますが、少し解像度が荒くなっています。ご容赦下さい。（何とか動作は確認出来ると思います。。。）


![kataban-shoukai_MP4_AdobeCreativeCloudExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2496293/e2c63fac-6ab2-cb46-8d04-ca1040bffa52.gif)


###自己評価

簡単に試作した割には、正しく画像認識できています。試作ということで3種類の機器しか判別できないものの、もっと多くの機器を学習させることで、実際に使えるレベルに発展させることが出来そうです。
使用感の改善では、推論が出るまで画像識別を繰り返し、識別出来た結果の画面表示は維持すべきかと考えています。（結果表示をしたら、再度ボタンを押さないと次の識別を開始しないようにする。）
firestoreのコレクション内データをtimestampでソートする

#具体例
消費期限前の果物をbeforeTodayFruitsList
消費期限後の果物をafterTodayFruitsList
にふり分ける（そんな運用はしないだろうけど…）。

#方法1：firestoreの複合インデックスを使用する
firestoreのインデックスタブ、複合インデックスを作成し、item_idとstarted_idをAscendingで登録したのち、以下記述する。
https://firebase.google.com/docs/firestore/query-data/index-overview?hl=ja#single-field-indexes

```
firebase
  .firestore()
  .collection('fruits')
  .where('item_id', '==', registor.docs[0].get('item_id').trim())
  //日付が若い順にソート
  .orderBy('expiration_date', 'asc')
  .onSnapshot(fruitsList => {
    // 本日と比較して未来と過去に分け、昇順で表示させる
    this.beforeTodayFruitsList = []
    this.afterTodayFruitsList = []
    fruitsList.forEach(value => {
      if (
        this.isBefore(value.get('expiration_date').toDate())
      ) {
        this.beforeTodayFruitsList.push(value)
      } else if (
        !(this.isBefore(value.get('expiration_date').toDate()))
      ) {
        this.afterTodayFruitsList.push(value)
      }
    })
```


#方法2：sort()を使用する
this.beforeTodayFruitsListは昇順
this.afterTodayFruitsListは降順
にそれぞれソートしたい場合は複合インデックスで事足りないので以下。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
https://stackoverflow.com/questions/7555025/fastest-way-to-sort-an-array-by-timestamp

```
firebase
  .firestore()
  .collection('fruits')
  .where('item_id', '==', registor.docs[0].get('item_id').trim())
  .onSnapshot(fruitsList => {
    // 本日と比較して未来と過去に分け、未来は昇順、過去は降順に表示させる
    this.beforeTodayFruitsList = []
    this.afterTodayFruitsList = []
    fruitsList.forEach(value => {
      if (
        this.isBefore(value.get('expiration_date').toDate())
      ) {
        this.beforeTodayFruitsList.push(value)
      } else if (
        !(this.isBefore(value.get('expiration_date').toDate()))
      ) {
        this.afterTodayFruitsList.push(value)
      }
    })
    this.beforeTodayFruitsList.sort(function (a, b) {
      return a.get('expiration_date') - b.get('expiration_date')
    })
    this.afterTodayFruitsList.sort(function (a, b) {
      return b.get('expiration_date') - a.get('expiration_date')
    })
```
【Project Euler】Problem 63: べき乗の桁数

* 本記事は[ProjectEuler](https://projecteuler.net/about)の「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

### 問題 63. べき乗の桁数

原文 [Problem 63: Powerful digit sum](https://projecteuler.net/problem=63)

**問題の要約：$a^n$の桁数が$n$になるような$a^n$の個数を求めよ**

例：
* $16807=7^5, 134217728=8^9$

$a$の上限が9, $n$の上限が21であることが分かれば後は簡単です。

```python
print(f"Answer: {sum([len(str(a**n)) == n for a in range(1,10) for n in range(1,22)])}")
```

（開発環境：Google Colab）
論文まとめ：Speech Emotion Recognition with Multi-task Learning

# はじめに
INTERSPEECH 2021 というカンファレンスから以下の論文
[1] X. Cai, et. al. Speech Emotion Recognition with Multi-task Learning
のまとめ

- 論文のリンク:
https://www.isca-speech.org/archive/interspeech_2021/cai21b_interspeech.html

- GitHubコード:
https://github.com/TideDancer/interspeech21_emotion

- コンペと結果:
https://paperswithcode.com/sota/speech-emotion-recognition-on-iemocap
ここで見つけた

# 概要
- 音声からの感情認識(Speech Emotion Recognition: SER)を行うモデル
- ベースとするアーキテクチャは wav2vec-2.0
- 音声からtextを推定すると同時に音声から感情を分類するというマルチタスクで学習を進める
- IEMOCAPのdatasetでSOTAを達成した


# related work
この分野は詳しくないので、ここも簡潔にまとめ

## SER に関して昔の手法
- ピッチ、エネルギー、フォルマント、メルバンドエネルギー、メル周波数、ケプストラム係数、を特徴量として用いたり、音声レベルの特徴量を用いる
- これらの特徴量をSVMやLDA（線形判別分析）、QDA（２次判別分析）、HMM（隠れマルコフモデル）に入力して分類した

## SER に関して Deep Learning 登場以後
- Deep Learning登場後初期はCNNやLSTMを用いた手法
- その後 self-attention を用いた手法が登場

## Wav2Vec-2.0 に関して
- BERTが自然言語処理の様々なタスクでfine-tuneされて用いられるのと同様に、wav2vec-2.0も音声認識タスクでfine-tuneされて用いられている
- wav2vec-2.0は自己教示あり学習も行なっていて、これにより高性能なモデルとなっている


# モデルのネットワーク構造

モデルのネットワーク構造は以下。

![スクリーンショット 2022-01-31 11.56.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/1b38180c-69f7-fb13-0a35-24bce3987c1e.png)

まず学習時は上図の左側。図中下の音声を事前学習したwav2vec-2.0に入力し、特徴量を出力する。

ここから感情を学習する青い部分とテキストを学習するオレンジの部分に分かれる。感情を学習する部分では特徴量をpoolingした後に全結合し、感情を推定する。

一方でテキストを学習する部分では全結合し、テキストを推定する。

# 学習と推論

- テキストを学習する部分は CTC lossを用いる
- 感情を学習する部分は 交差エントロピー lossを用いる
- この両者のlossを最小化するよう学習する

# 実験と結果
## IEMOCAP datasetを用いた定量的評価

![スクリーンショット 2022-01-31 11.56.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/05fdbc02-d5dd-25ed-bb2b-9bede3f673ff.png)

他の手法よりかなりよい。ただし、他の手法がどのようなモダリティを使っているかは不明。

# ablation study
ここでは loss において

```math
\min_{\theta, \phi} \mathcal{L} = \mathcal{L}_{\rm CE} + \alpha \mathcal{L}_{\rm CTC}
```

右辺１項目交差エントロピー loss と右辺２項目CTC lossとの比を調整する係数 $\alpha$ を変化させ、その精度を測定することで、テキストを学習する部分の効果を検証した。結果は以下。

![スクリーンショット 2022-01-31 11.56.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/e36ec973-d93c-124d-b5a3-1e701e56330e.png)

まず、αが0の時に比べて、$\alpha > 0$ の方がよいので、テキスト学習部分の効果は有ると言える。

特に $\alpha = 0.1$ の場合が最も良い。
Quick Start: Explore the Visualforce to LWC Sample App


# Deploy the Visualforce to LWC Sample App

+ We can't find the 'Visualforce to LWC' sample app.

もう一度この手順を試してみる。
[VisualforceからLWCへ](https://github.com/trailheadapps/visualforce-to-lwc/blob/main/README.md#installing-the-app-using-a-developer-edition-org-or-a-trailhead-playground)


11.App Launcherで、[すべて表示]をクリックし、Visualforce toLWCアプリを選択します。

こんどはあった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/17c77fe3-96a1-345e-aa7c-0181bab500fe.png)

えええ、もしかしてスクラッチ組織なので検証できない？

下の方を見るとパッケージをインストールするか、プレイグランドに対してデプロイするようなことが書かれている。
何度やってもプレイグランドにはデプロイできない。よく分からんエラーだ。

しかたないので、パッケージをインストール。

+ We can't find the 'Visualforce_to_LWC' permission set assigned to your user.

はいはい、スキップしろって書いてあるのに...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/5a04c95d-6449-b1ae-4b44-a5f7825fede6.png)

+ We can't find the sample data in the Visualforce to LWC app. Make sure you completed the steps under 'Installing the App using a Developer Edition Org or a Trailhead Playground' in the Visualforce to LWC project readme file.

データも要るの？　面倒くさいなぁ。

重複エラーが出るんですが、どこにもない。

sfdx force:org:list でどこにつながっているかを確かめてみます・
えええ、何だ？　思ったところにつながってないかも。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/fb82f6fc-f89d-90a6-f84d-9f6fa5c553cf.png)

以下のコマンドでログアウトさせてみました。
sfdx force:auth:logout -p

正しい接続先だけにしたら、無事インポートできました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/db67fb9a-a809-e226-af72-6627509e7c8f.png)

# Explore the Visualforce to LWC Sample App

何もせずに検証ボタンをクリック。

+ We can't find a contact named 'Yan Khang'.

混合レコードのところで、取引先責任者と商談をつくるボタンをクリックすればOKでした。
SVG artistaで簡単にSVGアニメーションを作る

## イラストレーターでSVG画像を作成する
Illustratorで線画と塗りありの２つのSVGデータを作成し、書き出し（アウトライン化する）
この時、線画の方はパスのつなぎ目のどこか１つをカットする

## SVGを合成する
先程書き出したSVGデータ２つをエディタで開き、塗りの方の＜g＞~＜/g＞までを、
線画の方の＜/svg＞の手前に入れて保存

（例）
```html:index.html
<!--    線-->
<svg xmlns="">
    <defs>
        <style>.d{}</style>
    </defs>
    <g id="a"></g>

   <!--    塗り-->     
    <defs>
        <style></style>
    </defs>
    <g id="e"></g>
</svg>
```


## SVGartistaを開く
https://svgartista.net に入り、左上のopen SVGより先程合成したSVGを選択する。

## 好みの秒数を設定して完成

＊STROKEANIMATIONのstaggerstepを０にして、animationdurationを3sなどにすれば、同時に線画の描画が始まる

:::note warn
左のバーの設定を「animation」にすると自然に発火し、「transition」にすると、.activeが振られた際に発火する仕様のため、
ローディングアニメでは「animation」にする。
:::
Teachable Machineを使って社内便の仕分けを簡単にしました

#1.はじめに#
小売業で人事をやっているKAZUと言います。今回Teachable Machineを使用して、社内便の仕分け時間を短縮する仕組みを作りました。

#2.課題と解決策
私の会社は毎日各店舗からさまざまな社内便が本部に送られてきます。メール室で人事部門、総務部門など部門別の仕分けがされ、人事部門の社内便が人事に届きます。

人事ではさらに社内便の表紙に記載された手書きの添付書類名を見て課、担当者別に再仕分けをします。仕分け作業は人事で当番制です。

しかし、人事内でも課が違うと誰が何をやっているか把握できず、書類名を見てもどの課、担当かわからないことが毎回発生します。

そこでTeachble Machineを使って手書きの書類名を読み取り、書類名から担当課、担当者、座席番号を表示させ、仕分けに困らない仕組みを作りました。

#3.使用したツール
・Teachable Machine
・CodePen

#4.作成手順

##4-1.Teachable Machineに種類名を登録し機械学習させる
社内便で届く書類名ごとにパターンを作り登録します。
①通勤手当申請書
②採用申請書
③社宅申請書

書類名は__手書き__のため、__手書きのパターンを複数登録__しました。
![申請書パターン.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2476779/245af451-4000-4046-4d41-72012a4bc388.png)

##4-2.CodePenにTeachable Machineで機械学習させたモデルを読み込む
Teachable Machineで学習させたモデルをCodePenに読み込んで推論を返します。例えばTeachable Machineで『通勤手当申請書』と出力された場合は、『労務課　田中さん　席番号315』が推理で返るようにします。

![担当課.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2476779/61a7f1c1-0ea7-7f22-c420-86c85464f04b.png)

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="ZEaEVKm" data-user="welkazuki" 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/welkazuki/pen/ZEaEVKm">
  書類の仕分け</a> by Welkazuki (<a href="https://codepen.io/welkazuki">@welkazuki</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

##4-3.結果
このように手書きされた書類名を認識し、担当する課、担当者、席番号が表示されます。これで困ることはありません。
（gifだと画面が小さくなってしまうためYoutube動画です）

https://youtu.be/AjptB80OkG0

##5.課題
手書き文字だと筆跡が人で異なるため、どの程度パターンを用意すれば、判断精度が高くなるか検討が必要です。手書きであれば費用が許せばAI OCRで読み込んで推論を返すほうが、簡単かもしれません。
VaadinのLive Reload方法

# Vaadin

https://vaadin.com/

アプリケーション起動中にソースコードを変更した際に明示的な再起動を伴わずに即時反映する方法を調べたので記事に起こします。

公式サイトの以下を参考にしています。

https://vaadin.com/docs/latest/flow/guide/step-by-step/running/#redeploying-during-development


## Redeploying During Development

>When you save a source file, the IDE automatically compiles it. The web server tracks the compiled files and automatically redeploys the application when it notices a change. You can then refresh the page to use the updated version.
You can also enable live reload to have the page refreshed automatically, as described in Live Reload.

## Live Reload

https://vaadin.com/docs/latest/flow/configuration/live-reload

フロントエンド側のコード（css,js,tsフォルダ内のファイル）はwebpack-dev-serverが変更監視をしていて、サーバサイド側のコード（java）はSpring Boot Developers Toolsがサポートするそうです。
厳密にはもう少し選択肢がありますが正確には上記リンクから英語ドキュメントを参照してください。

### Spring Boot Developers Tools

https://vaadin.com/docs/latest/flow/configuration/live-reload/spring-boot

pomに記述を追加するだけです。vaadinの公式からダウンロードするプロジェクトには最初から書いてありました。

```xml
<dependencies>
    ...
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>
```

これで動かない場合はintellijを使っている場合は設定を見直してください。
intellijのバージョンによって代わってくるのですが以下の２点です。

1) build project automatically

https://medium.com/@bhanuchaddha/spring-boot-devtools-on-intellij-c0ab3f9afa63

2) 2021.2の場合は以下でアプリ起動中にコンパイルを許可する

https://stackoverflow.com/questions/69449905/how-to-enable-spring-boot-live-dev-tools-on-intellij-2021-2-to-rebuild-classes-a

なお、上記はVaadinに限らずにintellij+springの場合も有効なはずです。（vaadinはバックにspringがあり、spring側の設定をいれて変更を反映する仕組みのようです）
have i been pwned? の使い方

# 概要
メールアドレス、電話番号を入力するだけで、個人情報やパスワード漏洩を確認することができるサイト「Have I Been Pwned?」の使い方をご紹介します。
https://haveibeenpwned.com/

このサービスには、110億件以上の漏えいアカウント情報が蓄積されていて検索するとデータベースに一致した情報を表示してくれます。

類似の確認サービスは多数ありますが、無料の上、信頼性が高く、全世界でもっとも信用されているのが「Have I Been Pwned?」という「漏えいの可能性があるメールアドレス／パスワード／電話番号を検索して、リスクや漏えい元を教えてくれる」サービスです。
全世界のセキュリティ研究機関や、FBIのような公的捜査機関とも連携しています。

作成したのはMicrosoftの地方支配人であり、セキュリティ開発者としてMVPも受賞したことがあるトロイ・ハントさんという方。
誰もが自分の保有するアカウントの危険性を無料かつ簡単にチェックできるようにするため、このサービスを作成したそうです。

# 使い方
##表示内容
![スクリーンショット 2022-01-31 11.23.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275960/a8e084dc-def0-3c3a-c0a1-b7be9537722e.png)
##検索
### メールアドレスを検索する場合
メールアドレスはそのまま入力します。
### 電話番号を検索する場合
電話番号は「国番号」をつけて記入します。
日本の国番号は「81」なので、電話番号の冒頭の0を取って81に続けて入力し、「pwned？」をクリックします。
```03-1234-5678 → 81312345678```
```090-1234-5678 → 819012345678```
###確認
漏洩してない場合
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275960/9069c65a-8a4a-0c5b-6062-90506fa1fab2.png" width="500">
漏洩している場合
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275960/2647fd8c-08a7-e5ae-9b75-f89ec95e0055.png" width="500">
##通知
将来、自身のメールアドレスが漏洩し、このサイトへ記録された時にメール通知してくれる機能もあります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275960/ae0d8ab5-82b9-ece0-2f48-815f789583c9.png" width="500">

##APIの利用
ドキュメントはこちらです。
https://haveibeenpwned.com/API/v3
画像をコラージュする

#画像を組み合わせて一枚の画像を作る方法です

<img width="560" alt="スクリーンショット 2022-01-31 11 38 13" src="https://user-images.githubusercontent.com/23278992/151731719-77e6b08e-0bd4-4729-91a8-da2e0bbef335.png">

#複数の画像から新しい画像を作りたい
複数の画像を組み合わせて一枚の画像にするとなると、はて、どうすればいいのか、、、と改めて思いました。

#Contextに描画すればいい

```swift
UIGraphicsBeginImageContextWithOptions(CGSize(width: outputWidth, height: outputHeight), false, 0.0)

imageA.draw(in: drawRectA)
imageB.draw(in: drawRectB)
imageC.draw(in: drawRectC)

let assembledImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
```

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

Core MLやARKitを使ったアプリを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
災害拠点病院一覧のPDFをCSVに変換

https://www.mhlw.go.jp/content/10800000/000773371.pdf

```python
import pathlib

import camelot
import pandas as pd
import requests


def fetch_file(url, dir="."):

    p = pathlib.Path(dir, pathlib.PurePath(url).name)
    p.parent.mkdir(parents=True, exist_ok=True)

    r = requests.get(url)
    r.raise_for_status()

    with p.open(mode="wb") as fw:
        fw.write(r.content)
    return p

# ダウンロード

url = "https://www.mhlw.go.jp/content/10800000/000773371.pdf"

p = fetch_file(url)


# PDF変換

tables = camelot.read_pdf(
    str(p), pages="all", split_text=True, strip_text=" 　", line_scale=40
)

dfs = [pd.DataFrame(table.data[1:], columns=table.data[0]) for table in tables]

df0 = pd.concat(dfs).set_index("No")

df1 = df0.copy()

df1["都道府県"] = df1["都道府県"].str.extract("(.+[都道府県])").fillna(method="ffill")

df1

df1.to_csv("災害拠点病院一覧.csv", encoding="utf_8_sig")

# 基幹・地域　集計
df2 = pd.crosstab(df1["都道府県"], df1["区分"])

df2

# 基幹・地域　抽出

df3 = (
    df0["都道府県"]
    .str.split(expand=True)
    .dropna(how="all")
    .rename(columns={0: "都道府県", 1: "基幹", 2: "地域"})
)

df3.set_index("都道府県", inplace=True)

df3["基幹"] = (
    pd.to_numeric(df3["基幹"].str.replace("基幹", ""), errors="coerce")
    .fillna(0)
    .astype(int)
)

df3["地域"] = (
    pd.to_numeric(df3["地域"].str.replace("地域", ""), errors="coerce")
    .fillna(0)
    .astype(int)
)

df3

# 基幹・地域 確認
(df3 - df2).reindex(df3.index)
```
VBAでの2次元配列の初期化方法 3種類 (備忘録)

# VBAで2次元配列を定義する

中身が所定の値をもつ2次元配列を手っ取り早く定義する方法をまとめてみました。備忘録に

### 1. For文で定義
まずは、普通にFor文を回す方法。単純に面倒。

```vb:case1
Public Sub arrayTest1()
    Dim arr1 As Variant, arr2 As Variant
    Dim i As Long, j As Long
    
    '---- 配列の定義-----
    ReDim arr1(2)
    ReDim arr2(1, 2)
    For i = 0 To 2
        arr1(i) = i + 1
    Next
    
    For i = 0 To 1
        For j = 0 To 2
            arr2(i, j) = j + 3 * i + 1
        Next
    Next
    
    '---- 出力テスト-----
    Debug.Print "arr1の中身"
    For i = LBound(arr1) To UBound(arr1)
        Debug.Print "要素"; i; ":   "; arr1(i)
    Next

    Debug.Print "arr2の中身"
    For i = LBound(arr2) To UBound(arr2)
        For j = LBound(arr2, 2) To UBound(arr2, 2)
            Debug.Print "要素"; i; "-"; j; ":  "; arr2(i, j)
        Next
    Next

    '----- 出力 ----
'    arr1の中身
'    要素 0 :    1
'    要素 1 :    2
'    要素 2 :    3
'    arr2の中身
'    要素 0 - 0 :   1
'    要素 0 - 1 :   2
'    要素 0 - 2 :   3
'    要素 1 - 0 :   4
'    要素 1 - 1 :   5
'    要素 1 - 2 :   6

End Sub
```

ローカルウィンドウを見ると、下記のような配列ができていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80231/be23d379-08fc-8598-e339-dedf15ac9972.png)


### 2. Array関数で定義
1次元ならArray関数で良さそう。2次元以上になると、すこし面倒。

```vb:case2
Public Sub arrayTest2()
    Dim arr1 As Variant, arr2 As Variant
    Dim i As Long, j As Long
 
   '---- 配列の定義-----
    arr1 = Array(1, 2, 3)
    arr2 = Array(Array(1, 2, 3), _
            Array(4, 5, 6))

    '---- 出力テスト-----    
    Debug.Print "arr1の中身"
    For i = LBound(arr1) To UBound(arr1)
        Debug.Print "要素"; i; ":   "; arr1(i)
    Next

    Debug.Print "arr2の中身"
    For i = LBound(arr2) To UBound(arr2)
        For j = LBound(arr2(1)) To UBound(arr2(1))
            Debug.Print "要素"; i; "-"; j; ":  "; arr2(i)(j)
        Next
    Next
    
End Sub
```

あとは、ローカルウィンドウを見ると、出来上がる配列が、For文で作ったときと異なり入れ子？みたいになっている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80231/ba909bc9-2578-fb23-f5fb-3317f80d0213.png)

### 3. 配列リテラルで定義
2次元配列を手軽に定義するなら、一番シンプルに書ける。

```vb:case3
Public Sub arrayTest3()
    Dim arr1 As Variant, arr2 As Variant
    Dim i As Long, j As Long

   '---- 配列の定義-----
    arr1 = [{1,2,3}]
    arr2 = [{1,2,3; 4,5,6}]

    '---- 出力テスト-----       
    Debug.Print "arr1の中身"
    For i = LBound(arr1) To UBound(arr1)
        Debug.Print "要素"; i; ":   "; arr1(i)
    Next

    Debug.Print "arr2の中身"
    For i = LBound(arr2) To UBound(arr2)
        For j = LBound(arr2, 2) To UBound(arr2, 2)
            Debug.Print "要素"; i; "-"; j; ":  "; arr2(i, j)
        Next
    Next
    
End Sub
```

ただし、配列の始まりが0ではなく、1になっていることに注意が必要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80231/73451ca7-2ee1-36a0-3424-0ce4eff44b3c.png)
Next.jsで作ったアプリをvercelにデプロイする時のエラー対応

Next.jsデータをvercelにデプロイする時のエラー解消の忘備録。

#前提
Next.jsで作ったアプリをvercelにデプロイしようとしたところ下記のエラーで進まなくなってしまった。


> Build optimization failed: found page without a React Component as default export in 
pages/config/firebase
See https://nextjs.org/docs/messages/page-without-valid-component for more info.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Error: Command "yarn run build" exited with 1

要約すると、コンポーネントが見つからないという内容のようだ。（この場合はpages>config>firebaseが見つからない。）

#結論
Next.jsではディレクトリ構造によってルーティングが決まるという性質があるらしく、'pages'ディレクトリ内には原則的にページの表示内容のファイルのみを置く必要がある。（'api'ファイルは例外。）
そのため今回はfirebaseの設定ファイルである'config'ディレクトリを'pages'内に作ってしまったことでエラーになった。

#解消方法
'config'ディレクトリを'pages'ディレクトリの外に移動させることで解消できた。
'src'ディレクトリを新たに作成し、その中に'pages'と'config'を入れる形でも良い。
　src/
　├config/
　｜　└firebase.js
　└pages/
　　　└index.js
【LevelUp】先輩から学ぶレビュー術

先輩エンジニアになると
『レビュー業務』が発生します💦

普通にゴリゴリOSSとかに参加して
バチバチトークするぜ！！って人以外は
『自分以外のソースに触れ、かつ指摘する』なんてことはしないです。

ってことで
誰かの指針になれば


#美しいか　美しくないか　ただそれだけだ
汚いソース＝だいたいバグってます。。。

間違っているところは
本来試験で確認するところなので
そこまで力を入れてレビューする必要はない。
（※ちゃんと試験をしているのが前提）


#ぱっとみなんか汚いと思ったら絶対他にいい方法がある
だいたい先人たちが同じことやろうとしてたはずなので
既に標準関数にあります。探しましょう。

「めちゃくちゃ配列操作してる = ライブラリ探す」
「ifが大量 = クラス構成見直せは改善する」


#GitHubはやはり優秀
クローズしたプルリクでたくさんコメントついてそうなのを見つけて
内容を確認し、同じ指摘うけないようにする！！
UDPフラッド攻撃 とは

## 勉強前イメージ

フラッド？？

## 調査

### UDPフラッド攻撃 とは

DDoS攻撃の一種で、偽ったIPアドレスからDDoS攻撃を行うものになります。

そもそもDDoS攻撃とは、
複数のマシンを乗っ取った上で攻撃目標であるサイトやサーバに対して大量のデータを送り付けることで行われる攻撃です。

UDPはコネクションレス通信のため悪用されやすく、攻撃側は少ないリソースで攻撃できる特徴があります。
コネクションレスのため、送信元IPの偽装がしやすく逆に防御が困難という特徴があります。

UDPフラッド攻撃にもいくつか種類があります。

### UDPフラッド攻撃の種類

種類としては以下の2種類です。

- ランダム・ポート・フラッド攻撃

サーバのランダムなポートにUDPのパケットを大量に送信することでサーバの停止を行う攻撃です。
サーバはポートで待機しているアプリケーションを繰り返し確認します。
このプロセスを大量に処理を行うことでサーバのリソースの消費を促します。

- フラグメント攻撃

大きなUDPのパケットを大量に送る攻撃です。
逆に、小さいパケットを送ることもでき、
ネットワークやサーバなど、環境に対してリソースを消費します。

### 対応策

対応策としては以下になります。

- UDPフラッド攻撃 や DDoS攻撃に対応したfirewallなどの導入
- OSでの設定の確認
- 不要なUDPのポートは開けない

## 勉強後イメージ

実はDDoS攻撃っていっぱいある？
今度調べてみよ。

## 参考

- [UDP flood/UDP Storm](https://securitychecklist.net/security/cyber-attack/UDP-flood.html)
- [DDoS攻撃の主な攻撃手法8つの特徴をまとめてみた](https://www.shadan-kun.com/blog/measure/1426/)
テレワークでサボってない？そんな上司の不安に応えたいLINE Bot

皆さんテレワークされてますか？
私の働いている会社ではコロナでの出勤人数制限が進み、テレワークをしている人が多くいます。
そんな最中雑談半分で本当にテレワーク中まともに働いてるの？と言われたので少なくともPCの前にはちゃんと座っていることで上司を安心させてあげようと思いました笑

#作ったもの
カメラの前から一定時間いなくなるとLINEへメッセージが飛ぶ監視装置

#こんなふうに動きます(動画)
<iframe width="560" height="315" src="https://www.youtube.com/embed/ZcbPliabNas" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

#使ったもの
- Teachable Machine
- codepen
- LINEmessagingAPI 
- Node-red

#レシピ
##1. Teachable Machine
画像モデルを使用し、機械学習させる。
通常業務中=カメラの前で普通に座っている
離席中=画面にいない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2491573/b79493c7-89d9-c7fc-898a-2521cebdde52.png)

##2. codepen
ボタンを押すとカメラが起動、カメラから読みとった画像をTeachable Machineで作成した機械学習モデルに送り推論を返してもらう。結果離席中が継続するごとに変数でカウンタを積み増し、閾値を超えたらNode-redへデータを送信する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2491573/81aab265-f83f-86dd-f939-c644d8676d80.png)

<p class="codepen" data-height="300" data-default-tab="css,result" data-slug-hash="qBVOWxb" data-user="kkaammaaddoo" 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/kkaammaaddoo/pen/qBVOWxb">
  カメラを止めるな！</a> by T.N (<a href="https://codepen.io/kkaammaaddoo">@kkaammaaddoo</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

```javascript
//離席回数カウンタ
let counter = 0;
//画像の結果が離席の時変数counterでカウントアップ
if (results[0].label == '離席'){
   counter = counter + 1;
   console.log(counter);}
   else{
       counter = 0
       console.log(counter);}

//離席カウンターが特定の値を超えたらnord-redにデータ送信
if (counter == 5) {
axios.post('https://nodered-tn046.herokuapp.com/receiver',);}      
```
##3. Nord-red
Nord-redでは下記のフローとした。
codepen側からデータ送信、Nord-redでデータを受信すると、
msg.payloadへメッセージを文字列で代入し、メッセージをLINEへ送信する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2491573/005b40f9-fe99-21e4-6eb8-021e1a825999.png)


#まとめ
チャレンジ内容としてはボチボチ動いたな～と言うのが実感です。
Teachable Machineに学習させる内容を赤外線カメラでも変えられたら、どこでも動作できそうですね。
こんなものが実装されない日を祈ってます笑
Swift Rxで音声の出力先を取得する方法

## コード
```swift

        AVAudioSession.sharedInstance()
        NotificationCenter.default.rx
            .notification(AVAudioSession.routeChangeNotification)
            .map {
                $0.userInfo?[AVAudioSessionRouteChangePreviousRouteKey] as? AVAudioSessionRouteDescription
            }
            .bind(to: Binder(self) { me, desc in
                if let audio = desc?.outputs.first {
                    // 出力先の取得
                    print("audio portType:", audio.portType.rawValue)
                }
            })
            .disposed(by: disposeBag)

```

👇👇ポートタイプの一覧はこちらにまとめてます！👇👇
https://qiita.com/shin1007m/items/6318e7648ad7232551da
ヒアドキュメントについて

rubyシルバーを勉強していくなかで、hashについてちゃんとわかっていなかった今回は解説させていただこうとおもいます。

##ヒアドキュメントとは
複数行にわたる長い文章の文字列を扱い場合に便利な機能のことです。
言われてもピンとこないとおもいますので、実際にコードを見ていきましょう
ヒアドキュメントを使わないときと、使うときで比較してみていきましょう

```
puts "ヒアドキュメントを使わない場合はこのようにクオーテーションで囲い、\n改行したい箇所に\\nを書くことで改行できる。\nちなみにバックスラッシュを二つ使うことで改行(\\n)をエスケープできる"
```

上の書き方は、ヒアドキュメントを使わない書き方です。これでも、コード上は何も悪いわけではないのですが、なんか見た目悪くないですか？
可読性が落ちるんですね。
では次に、ヒアドキュメントを使う書き方を見ていきましょう。

```
text = <<EOS
ヒアドキュメントを使わない場合はこのようにクオーテーションで囲い、

改行したい箇所に\\nを書くことで改行できる。

ちなみにバックスラッシュを二つ使うことで改行(\\n)をエスケープできる
EOS

puts text

=> #ヒアドキュメントを使わない場合はこのようにクオーテーションで囲い、

改行したい箇所に\nを書くことで改行できる。

ちなみにバックスラッシュを二つ使うことで改行(\n)をエスケープできる
```

ヒアドキュメントを使うと、かなり見やすくなりましたね！

##ヒアドキュメントの使い方
今回では識別子に、EOSが使われていますが、EOSじゃなくてもいいんです。
慣習的に、EOS(End Of String), EOF(End Of File), EOL(End Of Line)が使われます。

でも、識別子が一致していれば、名前は何でもいいんです。
そのため、以下のような書き方でもOKです

```
text = <<HOGE
ヒアドキュメントを使わない場合はこのようにクオーテーションで囲い、

改行したい箇所に\\nを書くことで改行できる。

ちなみにバックスラッシュを二つ使うことで改行(\\n)をエスケープできる
HOGE

puts text

=> #ヒアドキュメントを使わない場合はこのようにクオーテーションで囲い、

改行したい箇所に\nを書くことで改行できる。

ちなみにバックスラッシュを二つ使うことで改行(\n)をエスケープできる
```

##インデントをつける場合
インデントをつけるときは、識別子の前に「-」をつけることでインデントがつくんです。

```
data = <<-EOF
  hoge
  fuga
  hogehoge
EOF
=> "  hoge\n  fuga\n  hogehoge\n"

puts data
#
  hoge
  fuga
  hogehoge
```

##インデントをつけない場合
インデントをつけないときは、識別子の前に「~」をつけることでインデントを排除できるんです

```
data = <<~EOF
  hoge
  fuga
  hogehoge
EOF

=> "hoge\nfuga\nhogehoge\n"
```

##実際に問題を解いてみましょう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2485775/2a07a0a2-7b6c-4f84-1f3e-b9df5e78647c.png)

※選択されている回答は間違っています
今回の問題では、識別子の前に「-」をついています。つまりインデントが適用されるんですね。
よって、この問題の正解は
" Hello,\n Ruby\n"
が正解です

以上です。

何か間違いがございましたら、ご教示いただけますと幸いです。
RailsでJavaScriptファイルからのパスの通し方

## 実現したいこと
RailsのJavaScriptファイル内に記載した、画像・音楽ファイルへのパスを正常に読み込ませたい✅


<br>
## 開発環境
Ruby 3.0.2
Rails 6.1.4.4

<br>

## 結論

<font color="DeepPink">JavaScriptファイル内で読み込む場合</font>
/assets/ファイル名というように指定します。（imagesやmusicなどは省略）

```javascript:hghg.js
var ASSETS = {
  sound: {
    music: "/assets/energy.mp3",
    ring: "/assets/tamborine.mp3",
  },
  json: {
    beatmap: "/assets/notes.json"
  },
  image: {
    'bg': "/assets/club.png"
  }
};

```
```text:ディレクトリ構成
app
├── assets
│   ├── images
│   │    └── club.png
│   └── json
│   │    └── notes.json
│   └── music
│        └── energy.mp3
│        └── tamborine.mp3

```

<br>
<br>


<font color="DeepPink">viewファイルのscriptタグ内に記載するか、```hghg.js.erb```のように、Rubyの埋め込みが可能な場合</font>
パスの指定を以下のように、```asset_path```を使用する。


```ruby:任意のファイル
var ASSETS = {
  sound: {
    music: "<%= asset_path("energy.mp3") %>",
    ring: "<%= asset_path("tamborine.mp3") %>",
  },
  json: {
    beatmap: "<%= asset_path("notes.json") %>"
  },
  image: {
    'bg': "<%= asset_path("club.jpg") %>"
  }
};
```

<br>

manifest.jsにassets内の読み込むフォルダを指定する。

```javascript:app/assets/config/manifest.js
//= link_tree ../images
//= link_tree ../music
//= link_tree ../json
```

これでOK！！



<br>


## エラー表示
間違ったパスの指定をしていた際のエラーも掲載しておきます🤯
下記コードのように、assets内の任意のファイルを相対パスで指定してもRouting Error（```No route matches [GET] ... /assets...```）になります。

```javascript:任意のファイル

var ASSETS = {
  sound: {
    music: "../../assets/music/energy.mp3",
    ring: "../../assets/music/tamborine.mp3",
  },
  json: {
    beatmap: "../../assets/json/notes.json"
  },
  image: {
    'bg': "../../assets/images/club.jpg"
  }
};
```
[![Image from Gyazo](https://i.gyazo.com/0fcc7011e9f4e5c16b5008cefb203719.png)](https://gyazo.com/0fcc7011e9f4e5c16b5008cefb203719)


<br>

## 最後に
このエラーで数日詰まり、解決記事も他になかったので本記事を執筆しました✏️
本記事が多くの悩める方に届けば幸いです！！！
【Project Euler】Problem 62: アナグラム立方数

* 本記事は[ProjectEuler](https://projecteuler.net/about)の「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

### 問題 62. アナグラム立方数

原文 [Problem 62: Cubic permutations](https://projecteuler.net/problem=62)

**問題の要約：立方数の5通りのアナグラムがすべて立方数になるとき、その最小の立方数を求めよ**

3通りの例は以下のようになり41063625が最小値となります。

```math 
 41063625=345^3,56623104=384^3,66430125=405^3
```

1から順番に立方数を求めてそれを文字列にしてソートしたもの（アナグラムの最小値）をキーとしてDICT型に格納していきます。

例えば$5^3=125$と$8^3=512$はソートすると"125"となるのでDICT型にキーを"125"で値が[125,512]となります。この値の個数が5になった時点で答えとなります。

```python
import itertools
def addPM(n):
  pms = "".join(sorted(str(n))) # use sorted string as a key of dict
  if pms in pmdict:  
    pmdict[pms].append(n)
  else:         
    pmdict[pms] = [n]
  return pms

pmdict = dict()
for i in itertools.count(345):
  pms = addPM(i**3)
  if len(pmdict[pms]) >= 5:
    print(pms, pmdict[pms])
    break
print(f"Answer: {pmdict[pms][0]}")
```

（開発環境：Google Colab）
【Swift】AVAudioSessionPortDescription PortType 一覧

## portTypeとは？

The value of this property can be any of the constants declared in Input Ports, Output Port Types, or I/O Port Types.

このプロパティの値は、入力ポート、出力ポートタイプ、またはI / Oポートタイプで宣言された定数のいずれかです。

## 一覧

| type name | description |
| --- | --- |
| lineIn | ドックコネクタのラインレベル入力 |
| builtInMic | iOSデバイスの内蔵マイク |
| headsetMic | 有線ヘッドセットのマイク。 ヘッドセットとは、ヘッドフォン出力がマイクとペアになっているアクセサリのことです。 |
| lineOut | ドックコネクタのラインレベル出力 |
| headphones | ヘッドホンまたはヘッドセット出力 |
| bluetoothA2DP | BluetoothA2DPデバイスでの出力 |
| builtInReceiver | 電話をしているときに耳に当てるスピーカー |
| builtInSpeaker | iOSデバイスの内蔵スピーカー |
| HDMI | 高品位マルチメディアインターフェースを介した出力 |
| airPlay | リモートAirPlayデバイスでの出力 |
| bluetoothLE | Bluetooth LowEnergyデバイスでの出力 |
| bluetoothHFP | Bluetoothハンズフリープロファイルデバイスでの入力または出力 |
| usbAudio | ユニバーサルシリアルバスデバイスでの入力または出力 |
| carAudio | カーオーディオによる入力または出力 |
| virtual | 実際のオーディオハードウェアに対応していない入力または出力 |
| PCI | PCI（Peripheral Component Interconnect）バスを介して接続された入力または出力 |
| fireWire | FireWire経由で接続された入力または出力 |
| displayPort | DisplayPortを介して接続された入力または出力 |
| AVB | AVB（オーディオビデオブリッジング）を介して接続された入力または出力 |
| thunderbolt | Thunderboltを介して接続された入力または出力 |
情報セキュリティマネジメントに合格したのでまとめた

令和3年度下期情報セキュリティマネジメント試験(以下SG)に受かりましたので、
当時を振り返って勉強方法などを話していきます。

それでは、以下に詳しく書いていきます。

## 試験概要
さらっと試験の概要を記載します。
令和3年度下期情報セキュリティマネジメント試験CBT方式
試験会場：各地にあるプロメトリックのテストセンター
受験手数料：￥7,500（消費税込み）
合否発表：メールで即時
試験時間：（午前）90分、（午後）90分
出題方式：午前午後ともに多肢選択式（四肢択一）
問題数：（午前）50問、（午後）3問
合格点：（午前）60点/100点、（午後）60点/100点

## 勉強方法
流れとしては、
①参考書を１周読む
②午前過去問を解きまくる
③午後過去問を解きまくる　　　をおすすめします。

実際のところ過去問から同じような問題から出題されますので、過去問を解きまくるだけで合格できるのも事実です。
ただ、参考書を読んだうえで過去問を解いたほうが将来的な知識の定着が違うためこの流れをお勧めします。

#### ①参考書を１周読む
 [出るとこだけ！情報セキュリティマネジメント テキスト＆問題集](https://www.amazon.co.jp/dp/B09HC74PPR/ref=cm_sw_r_cp_api_glt_QWSVT50BSG3R87M57MF1)
SG対策参考書も色々とありますが、最新版であれば何でもいいです。
私はこちらを買いました。
なんとなく書いてあることが分かってきたなぐらいになればおっけーです。

#### ②午前過去問を解きまくる
過去問ひたすら解くのみです。
とにかく過去問ひたすら過去問です。
平均8～9割とれるようになるまで解きまくりましょう。
間違った問題は即復習。
過去10回分は解いておきたいですね。

#### ③午後過去問を解きまくる
午前同様に過去問ひたすら解くのみです。
正直午前対策を十分やったあとなら初めてでもある程度解けると思います。

ただ、長文読解形式ですこし癖があり、問題に慣れる必要があります。
また、午前と比べて時間配分がギリギリになるため一度本番と同様に時間を計って通して解くことをお勧めします。

## さいごに
以上、当時のことを思い出しながら書いてみました。
本記事がSG合格の助けになれば幸いです。
次は基本情報術者試験を受ける予定ですので、良い結果出ましたらまた報告させていただきたいと思います。
【Project Euler】Problem 61: しりとり多角数

* 本記事は[ProjectEuler](https://projecteuler.net/about)の「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

### 問題 61. しりとり多角数

原文 [Problem 61: Cyclical figurate numbers](https://projecteuler.net/problem=61)

**問題の要約：4桁の多角数（３・４・５・６・７・８角数）6種類が2つの数字のしりとりで循環するような集合の和を求めよ。

言葉で書くと分かりづらいですが、条件としては、
* 4桁の多角数6種類（３・４・５・６・７・８角数）の集合
* 6つの数は後ろ2桁と前2桁が等しい2桁しりとりの形になり巡回する
* 多角数6種類の順番は自由

以下が多角数3種類の例です。

```math 
8128（三角数）2882（五角数）8281（四角数）
```

まず2桁しりとりのチェックする関数**isCytclic**。

```python
def isCyclic(n1, n2):
  return str(n1)[-2:] == str(n2)[:2]
```

次に4桁の多角数6種類（３・４・５・６・７・８角数）をすべてリストします。

```python
# Create a list of 4-digit poligon numbers 
FigNums = [[pn for pn in [f(n) for n in range(1,1000)] if len(str(pn)) == 4] for f in funclist]
```

後は再帰呼び出しで2桁しりとりの数を異なる多角数から循環するまで探索します。

```python
def findCyclic(foundList, remPolType):     # FoundList, Remaining Pol Type e.g [0,1,2]
  if len(foundList) == 6 and isCyclic(foundList[-1],foundList[0]): 
      return foundList+[0]    # Answer found = len(foundList) == 7
  
  for pt in remPolType:
    for nextnum in FigNums[pt]:
      if len(foundList) == 0 or isCyclic(foundList[-1],nextnum):   
        fl = findCyclic(foundList+[nextnum],remPolType-{pt}) # call findCyclic for remaining Pol Types
        if len(fl) == 7: return fl
  return foundList

remPol = set({0,1,2,3,4,5})
fl = findCyclic([],remPol)
print(f"Answer: {sum(fl)}, {fl[:-1]}") 
```

（開発環境：Google Colab）