OmniAICreator/Qiita-1.07M huggingface dataset:
PowerShellでJSONファイルを作成する方法

# はじめに
PowerShellを使用してJSON形式のファイルを作成する方法をご紹介します。ハッシュテーブルを作成し、それをJSON形式に変換し、結果をファイルに出力します。


# 作成方法
Powershellを開き、以下のスクリプトを張り付けてください
```powershell
# JSONに変換したいデータを定義
$data = @{
    Name = "John Doe"
    Age  = 30
}

# JSONへ置換
$jsonString = $data | ConvertTo-Json
# ファイル出力
$jsonString | Out-File -FilePath data.json

```

    


# PowerShellで階層構造や配列を含むJSONファイルを作成する方法

上記で基本的なJSONファイルの作成方法をご紹介しましたが、実際のデータはより複雑な構造を持つことがあります。たとえば、オブジェクトの中に別のオブジェクトが含まれる階層構造や、配列を含むこともあります。このセクションでは、そういった複雑なデータ構造をJSONに変換する方法を解説します。

## 階層構造のデータ

まずは階層構造のデータを作成してみましょう。以下の例では、"Name"と"Age"というプロパティを持つ"Person"オブジェクトが、"Address"オブジェクトを含む構造を作成しています。

```powershell
$data = @{
    Person = @{
        Name = "John Doe"
        Age  = 30
        Address = @{
            Street = "123 Main St"
            City   = "Anytown"
            State  = "CA"
            Zip    = "12345"
        }
    }
}
```

これを `ConvertTo-Json` コマンドレットでJSONに変換すると、以下のような階層構造のJSONが生成されます：

```json
{
    "Person":  {
                   "Name":  "John Doe",
                   "Age":  30,
                   "Address":  {
                                   "Street":  "123 Main St",
                                   "City":  "Anytown",
                                   "State":  "CA",
                                   "Zip":  "12345"
                               }
               }
}
```

## 配列を含むデータ

次に、配列を含むデータを作成してみましょう。以下の例では、"Name"と"Age"というプロパティを持つ複数の"Person"オブジェクトを配列として定義しています。

```powershell
$data = @{
    People = @(
        @{
            Name = "John Doe"
            Age  = 30
        },
        @{
            Name = "Jane Doe"
            Age  = 32
        }
    )
}
```

これを `ConvertTo-Json` コマンドレットでJSONに変換すると、以下のような配列を含むJSONが生成されます：

```json
{
    "People":  [
                   {
                       "Name":  "John Doe",
                       "Age":  30
                   },
                   {
                       "Name":  "Jane Doe",
                       "Age":  32
                   }
               ]
}
```

以上が、階層構造や配列を含むデータをJSONに変換する基本的な手順です。この方法を応用すれば、様々なデータ構造をJSON形式で出力することが可能です。
コンペで勉強になったことまとめ（2023年前期）

# 本記事の目的
本記事は、コンペに参加する中で、勉強になった項目の個人的備忘録です。
随時追加していく予定です。

# 勉強になった点
### ColumTransformer
公式リファレンス
https://scikit-learn.org/stable/modules/generated/sklearn.compose.ColumnTransformer.html#sklearn.compose.ColumnTransformer

公式リファレンスでは、ColumnTransfomerについて、
>この推定器は、入力の異なる列または列のサブセットを個別に変換し、それぞれの変換器によって生成された特徴量を連結して単一の特徴空間を形成することができます。これは，複数の特徴抽出機構や変換を1つの変換器にまとめることができるため，異種データや列データに対して有用である．

と書かれています。（DeepL訳）
- メリット
    - カラムごとに異なる処理ができる
    - ColumnTransfomerでは、オリジナルなtransformerも、TargetEncodingやOneHotEncodingなどの単一のtransformerの両方を使用することができる
    - パイプライン化できるので、処理が単純になる

- 使い方
    - インポート
    ```
    from sklearn.compose import ColumnTransformer
    ```

    - 処理内容と列を指定
    ```
    ct = ColumnTransformer(
        [
            ("scaling", StandardScaler(), ['numerical_column1', 'numerical_column2']),
            ("onehot", OneHotEncoder(), ['categorical_column1', 'categorical_column2'])
        ],
    )
    ```
    - 適用する
    ```
    X_transformed = ct.fit_transform(X)
    ```


    - 以下のようにpipline化も可能
    ```
    pipe = Pipeline(
        steps=[
            ("preprocess", PreProcessTransformer()),
            ("ct", ct),
        ]
    )
    ```
    - 新しい変換器は以下のように作成可能
        - TransformerMixinとBaseEstimatorクラスを継承し、そのメソッドをオーバーライドして独自の変換器を作成する。
        - https://scikit-learn.org/stable/modules/generated/sklearn.base.TransformerMixin.html
    ```
    from sklearn.base import BaseEstimator, TransformerMixin
    
    class PreProcessTransformer(TransformerMixin, BaseEstimator):
        def fit(self, X, y=None):
            # ここでXから必要な情報を学習します（例: 各列の平均値を計算する等）
            return self
    
        def transform(self, X):
            # ここでXを変換します（例: スケーリング、欠損値の補完等）
            return X
    ```
### TabNet　（https://arxiv.org/pdf/1908.07442.pdf）

- メリット
    - TabNetでは内部的に重要な特徴を選択し、無関係な特徴を無視できる。
    - TabNetはインスタンスごとの特徴の重要度を提供し、モデルの解釈を容易になる。
    - 他の多くのディープラーニングモデルと同様に、TabNetはデータ内の非線形関係を効果的に捉えることができます。
    - TabNetはスパースな特徴セットでも良好な性能を発揮します。

- デメリット
    - 大規模なデータセットの場合、TabNetのトレーニング時間は長くなる可能性があります。
    - TabNetの性能はハイパーパラメータの選択に大きく依存します。最適なパラメータを見つけるには多くの実験が必要です。
    - ディープラーニングモデルとして、TabNetは十分なメモリと計算リソースを必要とします。

- 使用方法
    - インポート
    ```
    pip install pytorch-tabnet
    ```

    - 学習・評価
    ```
    # モデルのインスタンスを作成
    clf = TabNetClassifier()
    
    # モデルをトレーニング
    clf.fit(X_train, y_train)
    
    # テストデータで評価
    preds = clf.predict(X_test)
    ```
Promise Executor の非同期例外 


JavaScript の Promise での非同期例外の扱い方を簡単に整理してみました。Promise Executor の中から、 **throw** で Error を投げる方法と、**reject** で Error を返す方法を比べてみました。結論から言うと、Promise Executor から Error を返す時は、throwではなくrejectを使う方が安全です。

[Promise の基礎知識 -- Qiita](https://qiita.com/sand/items/f37288fb3d40b964f83b)
[Promise でのエラーハンドリング](https://ja.javascript.info/promise-error-handling)




### １．同期エラーの場合は常にOK

同期エラーの場合は、throw と reject のどちらで返した場合も補足できます

* **throwでErrorを投げた場合 OK**
```javascript:OK
new Promise(function(resolve, reject) {
  throw new Error("Whoops!");
}).catch(err => console.log(err.message)); // Error: Whoops!
```

* **rejectでErrorを返した場合 OK**
```javascript:OK
new Promise(function(resolve, reject) {
  reject(new Error("Whoops!"));
}).catch(err => console.log(err.message)); // Error: Whoops!
```

### ２．非同期エラーの場合は、rejectの場合のみOK
同期エラーの場合は、reject で返した場合のみ補足できます

* **throwでErrorを投げた場合 NG**

```javascript:NG
new Promise(function(resolve, reject) {
  setTimeout(() => {
    throw new Error("Whoops!");
  }, 1000);
}).catch(err => console.log(err.message)); // Error: Whoops!
```

::: note warn
エラーメッセージ
VM87:3 Uncaught Error: Whoops!
    at <anonymous>:3:11
:::

非同期で throw で Error を投げられると、Promise catchメッソドでは補足できないようです。


* **rejectでErrorを返した場合 OK**

```javascript:OK
new Promise(function(resolve, reject) {
  setTimeout(() => {
    reject(new Error("Whoops!"));
  }, 1000);
}).catch(err => console.log(err.message)); // Error: Whoops!
```

非同期で reject で Error を返すと、Promise catchメッソドで補足できるようです。


### ３．非同期エラーの場合は、try/catchでも、rejectの場合のみOK

**try/catch** で処理する方法と、Promise catchメッソドの **Rejection handler** で処理する方法を実験しました。この場合もreject で返した場合のみ補足できます。


* **throwでErrorを投げた場合 NG**

```javascript:NG
function promiseFunc() {
  return new Promise(function(resolve, reject) {
    setTimeout(() => {
      throw new Error("Whoops!");
    }, 1000);
  })
}

try {
  await promiseFunc();
} catch (err) {
  console.log(err.message)
}
```

::: note warn
エラーメッセージ
VM91:4 Uncaught Error: Whoops!
    at <anonymous>:4:13
:::

非同期で throw で Error を投げられると try/catch でも補足できないようです。


* **rejectでErrorを返した場合 OK**

```javascript:OK
function promiseFunc() {
  return new Promise(function(resolve, reject) {
    setTimeout(() => {
      reject(new Error("Whoops!"));
    }, 1000);
  })
}

try {
  await promiseFunc();
} catch (err) {
  console.log(err.message)
}
```

非同期で reject で Error を返すと、try/catchでも補足できるようです。


今回は以上です。
SIGNATE Student Cup 2023 の感想

SIGNATE Student Cup 2023に参加し、25位で銀メダルという結果でした。
今回は備忘録も兼ねて、解法や初めて使ったライブラリなどまとめていきます。

## コンペについて
SIGNATE主催の、Student Cup 2023に参加しました。
Student Cupは毎年行われている？（去年も参加しました）いるコンペで、学生No.1データサイエンティストを決めるデータ分析コンペティションとされています。
モデリング部門とChatGPT部門があり、今回はモデリング部門に参加しました。

コンペの目的としては、中古自動車の情報(車種・走行距離など)をもとに、中古車の価格を予測するものでした。
今回の情報共有は、HP上のフォーラムではなく、Slack上で行われていました。（Slackを盛り上げた人に贈られる賞もあるそうです。）

## 解法
### 前処理
- LightGBM
    - stateはregionから一意に決定されるので、stateの欠損値はregionを参照することで補完
    - size, manufacturerの表記ゆれを修正
    - yearが3000以上のものは存在し得ないはずなので、2000年代に変更
    - cylindersから数値のみを取り出す
- NN
    - 数値の欠損はすべて平均で、カテゴリ変数の欠損は、欠損ということがわかるように補完しました（この辺りは改善できそう）
    - StandardScalerを使用

### 特徴量
- カテゴリ変数についてはtarget encoding
- 数値に関してはそのまま
- size_rankがカテゴリ型であったため、順位を明示したものを追加
    - 'full-size': 4, 'mid-size': 3, 'compact': 2, 'sub-compact': 1
- メーカー名から、どの国の車であるかを追加
- 車の色を、黒系、明るい系などにカテゴライズした特徴量を追加
- 走行距離 / 製造年　を追加
- 緯度経度（geopy）を追加
- condition, fuel, typeに関して、走行距離のaggregationを実施
    - 平均値、中央値
- 上記の平均・中央値と、走行距離の差分を追加

### 学習
 - LightGBMとNNを使用
 - 最終subは以下の2つを提出しました。（最後に選択したファイル2つのスコアが最終評価で一番よかったです）
     - LightGBM（60%）、LightGBM+geopy（30%）、NN（10%）：　43.3074128
     - LightGBM（55%）、LightGBM+geopy（35%）、NN（10%）：　43.3175492

## 他に試したこと
- catBoost
- tabNet
- XGBoost
- カテゴリ変数のOnehot
- aggregationに使用する変数の追加
- 上記のモデルのアンサンブル

## 改善点
- ハイパーパラメータの最適化を行うことができなかった。
- NN系は工夫次第で精度がまだ上がりそうなイメージ。
- 走行距離の重要度が高いので、欠損値を埋めるためのモデルを作ると良いらしい。
- catboostの予測結果を特徴量に追加して、LightGBMで予測すると、かなり精度が上がったらしい。
- 上位の方で、tabNetを使用していた方がいるらしい。
- 実験のコードと提出ファイルが途中でごちゃついて、同じファイルを提出していた（割と終盤に。。。）ので、コード管理を改める。

## 今回勉強になったこと
- 今回初めてcolumn transfomerを使用して便利だった。
- NN系のモデルで、テーブルデータにも精度高く使用できるtabNetというものがあることを知った。

## 感想
欠損値の補完や、特徴量の作成のみでは大幅な改善が見込め無さそうだったので、多くのモデルを試せたことは良かったです。
今回のコンペは金メダルを狙いにいっていたので、銀メダルという結果は納得のいくものではなかったですが、勉強になることが多いコンペだったので、次回以降Master目指して頑張っていきたいと思います。
jQueryのキーボードライブラリを作りたい話

どうもAtsu1209です。
早速ですが、キーボードとボタンを連動させたいと思って
jQueryをいじってたら一つ思いついたことが...
ライブラリ化してどこでも使えるようにしよう!
ということで キーボードライブラリ(自分用)を作ります。
# jQuery読み込み
まず jQueryを読み込まないと何もできません
```html:index.html
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
```
これを読み込みたいhtmlに書きます。

# ライブラリ作成
早速JSをかきます。
```javascript:lib.js
const button1 = document.getElementById("button1");
document.addEventListener("keydown", function(event) {
    if (event.key === "1") {
        button1.click();
    }
});
```
かなり適当なクラス名だけど、こんなかんじ
`keydown`を使用して、1キーを押したら `button1`のクラスの付いた
オブジェクトをクリックするようにしました。

これを全部のキーでかいて、`lib.js`を読み込めばok

# 最後に
なんか変なところあったらコメントおねがいします。
では また次の記事で!
Terraform と GCP でのプロジェクト別のリソース管理


# 概要

GCP で Terraform を使用する際、異なるプロジェクトや環境に対して効率的に Terraform を適用する方法について調べたので、それを本記事にまとめました。
Terraform の backend 設定を使用して、GCP上の Cloud Storage を使って異なるプロジェクトや環境ごとに Terraform state を管理する方法を以下に記載します。
これにより、リソースの競合や誤操作を回避し、一貫性のあるインフラ管理を実現することができました。



# 実装手順

1. バケットの作成
最初に、Terraform state を保存する Cloud Storage バケットを作成します。

1. Terraform の設定ファイル (通常 main.tf または backend.tf など) に backend の設定を追加します

    ```
    terraform {
      backend "gcs" {
        bucket  = "default_gcs_bucket_name"
        prefix  = "terraform/state"
      }
    }
    ```

1. backendの変更を適用するためにterraform initを実行します。

    ```
    terraform init -backend-config="bucket=terraform-backend_for_<プロジェクトID>"
    ```

    :::note info
    terraform init コマンドを実行する際に、-backend-config オプションを使用して動的に設定をオーバーライドすることができます。
    このオプションを利用すると、環境に応じて異なるバケットを使用することができます。

1. このコマンドを実行すると、以下のようなプロンプトが表示される場合がありますので、この質問に `yes` と答えることで、現在の state が新しい GCS backend にコピーされます。

    ```
    Do you want to copy existing state to the new backend?
    ```

1. terraform init の実行が完了したら、そのディレクトリで terraform apply を実行します。このとき、上記で設定した GCS bucket が backend として使用されることになります。
医用CVの前処理「データ拡張」に新しい手法をおすすめします:MedAugment

画像系でよくある医用画像に対して、非常に良いデータ拡張手法MedAugmentを共有したいと思います。

通常のデータ拡張手法、例えばAugmixやAutoAugmentは、一般的な画像処理には適していますが、
医用画像の分類やセグメンテーションにおいては性能が高くないことが多く、単純な回転や拡大の方が効果的な場合もよくあります。
MedAugmentは、医用画像に特化した手法です。

中身は少し複雑ですが、簡単に説明します。
開発者は、APとASの2つのデータ拡張操作グループを定義し、2つ合わせて14個の拡張手法を含む形で設計しました。
![4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/ca2de8bf-06c3-dd3f-ea64-6c4cf411b038.png)

これに基づき、特定の組み合わせを持つ「サンプリング戦略」が導入されています。さらに、独自の「マッピング戦略」もあります。
*APはピクセル(PIXEL)に関連する手法で、例えば、輝度、コントラスト、ポスタライズなどです。
*ASは空間(Spatial)に関連する手法で、例えば、回転、拡大、平行移動などです。



①サンプリング戦略:
医用データは輝度に非常に敏感で、連続的にAP操作を行うと、出力画像が実物とかけ離れ、モデルの学習に悪影響が生じます。
そのために、開発者は「モデルをまずM回のAS操作を行い、その中にランダムなAP操作を1回含むようにする。AP操作は1回以下で、Mは2回～3回」を条件として設定しました。

![６.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/6da32246-5d6a-2d5f-b47b-24395bc1191e.png)



②マッピング戦略:
MedAugmentに単一のハイパーパラメータを使用するため、開発者はiという単位を追加しました。このiは、各操作の強さをコントロールするために使用されます。
例えば、ポスタライズは学習の精度に大きな影響を与えるため、iはポスタライズのコントロールをより厳しくにし、結果としては学習がより良くなるといいます。
（こちらについての具体的な実現方法は私もよく理解していません。。）
![５.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/539a0ec4-2ebf-02db-35ee-99b02b480b0e.png)


MedAugmentはマッピング用のハイパーパラメータを一つだけにまとめて、それを「i」として表現しています。
この「i」は操作の強さを調整するためのものです。例として、ポスタライズは学習の精度に影響を及ぼすため、
「i」はポスタライズのコントロールをより厳しくにし、結果としては学習がより良くなるといいます。
（こちらについての具体的な実現方法は私もよく理解していません。。）


数年前Kaggleで行われた人間のタンパク質を分類するコンペのデータを使って、MedAugmentの効果をテストしました。
既存のコードはそのままで、データ拡張部分だけをMedAugmentにして、どれだけ精度が上がったのかを確認しました。
結果としては、精度自体(f1score)は約1.5%弱上がりました。（51.5%から53%）、全体的な学習過程もより安定にしています。
ただ、Valid lossを見ると、最後の振動が若干大きくなって、そちらをもっと収束すれば、さらに高い精度が得られるではないかと思います。
また、元のデータは約30,000件でなので、このデータ量でこのくらい性能出すのは結構良い手法だなと思いました。データ件数が少ない場合なら、更なる性能向上が期待できると考えています。

![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/2b143338-c44b-1005-b8ce-6fbf21d660fa.png)
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/9ee4fdb4-9426-a257-4499-188c3ac44914.png)




コードと論文は以下となります。興味あるは試してみてください。

コード：https://github.com/NUS-Tim/MedAugment
論文：https://arxiv.org/abs/2306.17466
初心者のためのVim学習コマンド一覧

# 初心者のためのVim学習コマンド一覧

## はじめに
私は現在、プログラミング学習をしており、学習を進める中でVimのことについて学習をしました。
本ブログでは、Vimとは何かということから、初心者がVimを扱うために必須のコマンドについてまとめましたので、Vimを、学びたい、扱いたいと考えている方には是非見ていただけると幸いです。

## Vimとは
Vimとは、エディタの一つです。CUI（コマンド・ユーザー・インターフェース）を前提に作られているため、マウスを使う設計にされておらず、コマンドを使ってフォルダーを開いたり、フォルダーの中を編集したりすることが出来ます。
ターミナルで動きますが、Vimを開いているときは、その開いているターミナルのタブは、１つのエディターとして考えます。
Vimを用いると、キーボードのみでコードを書くことが可能になるため生産性の向上が期待されます。

## Vimの操作コマンドステップ５
とはいっても、Vimはコマンドが数えきれないほどあるため覚えるのが大変なのです。（自分も現在このブログを作成するために初めて使っていますが、、、）
複数のステップにわたって、徐々に「これを知っているとよい」というコマンドを紹介します。

まずは基礎操作です。
### ＜移動＞
`h`　カーソルを左にずらす。
`j`　カーソルを下に下げる。
`k`　カーソルを上に上げる。
`l`　カーゾルを右にずらす。
### ＜入力と保存＞
`a`　カーゾルの場所から１文字つめてインサートモードに入る。
`i`　カーソルの場所からインサートモードに入る。
`x`　カーソルの直下の文字を消す。
`:w`　ファイルの保存
`:q`　実行中のタブを閉じる
`:wq`　上を組み合わせて、保存して閉じる。
`:w!`　のように、最後に！をつけると、強制的に処理を行う。

いかがでしょうか？なんやこれは！？って思いませんか？
大丈夫です、今これを書いているぼくも思っています。慣れれば劇的に使いやすくなるものらしいですので、一緒に最後まで頑張りましょう。

ここで、、、
Ｖｉｍのモードには、３種類あります。それをご紹介します。


#### 1.NormalMode（コマンド入力モード）
カーソルの移動・他のモードへの移行・テキストのコピー・カット・ペースト
起動の仕方：`Esc`
#### 2.InsertMode(文字入力モード)
起動の仕方：`a/i/A/i/ciw`
テキストの入力・編集
#### 3.VisualMode(文字選択モード)
テキストの選択
起動の仕方：`v`

### 〇ステップ１
まずは１ステップです。一緒にマスターしましょう！
#### ＜基本コマンド＞
`dd`　カーソルがある１列削除
`yy`　１列コピー
`p`　ペースト
`u`　操作を１つ戻す
`j`　カーソルがある行に1つ下の行を連結する。
#### ＜カーソル移動＞
`gg`　ページの一番上に行く
`Ｇ`　ページの一番下に行く
`Ｈ`　表示されている画面の一番上に行く。
`Ｍ`　表示されている画面の真ん中に行く。
`Ｌ`　表示されている画面の一番下に行く。
#### ＜ページ内検索＞
`/hoge`　/のあとの文字列を検索する。
`n`　/で検索した文字列の次の検索候補にとぶ。
`N`　/で検索した文字列の前のｎに索候補にとぶ。

この辺は必須みたいです。さて、どんどんいきましょう！

### 〇ステップ２
#### ＜文字の入力の応用＞
`A`　カーソルのある行の最後にインサートモードで飛ぶ
`I`　カーソルのある行の最初にインサートモードで飛ぶ
`.`　直前にやったことを繰り返す。
#### ＜カーソル移動＞
`$`　カーソルのある行の最後にノーマルモードで飛ぶ。
`^`　カーソルのある行の最初にノーマルモードで飛ぶ。
#### ＜VisualMode>
`v` インサートモードに入る
`v + 移動キー`　範囲選択が出来る
`v + (1) + y` 選択した範囲をコピー
`v + (1) + d` 選択した範囲を削除

この辺になると、正直もういいやってなってしまいそうです。ですが、最初や最後、インサートやノーマルを指定しながら一気に飛べるのは非常に便利ですね。
さて、つぎにまいりましょう！

### 〇ステップ３
#### ＜カーソルの移動をはかどらせるコマンド＞
`w`　１単語飛ばしてカーソルを右に動かす。
`e`　１単語飛ばして、カーソルを右に動かす。
`b`　１単語飛ばして、カーソルを左に動かす。

h,j,k,l があれば、忘れてしまいそうなコマンドですね。

### 〇ステップ４
#### ＜削除系のコマンド＞
`c`　ビジュアルモードで選択した範囲を消して、インサートモードで終わる。
`ci`　括弧の中身だけを消す。
`ciw`　カーソルの下にある１単語を消して、インサートモードに入る。
`cit`　hrmlタグに囲まれている中を消す。
`dw`　カーソルから右にある単語を消す。
`daw`　カーソルの下にある単語を消す。
`D`　カーソルから右にある分をすべて消す。
`S`　カーソルのある1行を消してインサートモードに入る。

気が遠くなりそうですね。たぶんこの辺は、もう使いこなしている方がカタカタやっているイメージではないかと自分は踏んでいます。
そういえば、スマートフォンで、単語帳のアプリを使い、Vimのコマンドの単語帳を自作しました。コツコツ覚えて、確かなスキルにしていきたいものです。
さて、次で最後です！

### 〇ステップ５
#### ＜その他の役立つコマンド＞
`:!{Shellコマンド}`　Vim内でShellのコマンドが使える
`m` `m+a~Z`で好きな行をマークしておいて、`` `+a~Z ``でマークしたところへ飛べる
`` ` ``　"
`~`　カーソル直下の文字の大文字、小文字を切り替える。
`%`　括弧がカーソル直下にある場合、　括弧終わり→括弧はじめ　に飛ぶ。
`U`　選択した範囲を大文字小文字切り替える。
`* + #`　カーソルの置いてある単語を検索する。
`:n`　nに数字を入れると、その行に飛ぶ。
`ggVG`　全て選択
`Control - v`　インサートモード(箱型)
#### ＜保存系＞
`ZZ`　変更があれば保存しゅうりょう。
`:x`　変更があれば保存して終了。
`:xa`　変更があるタブを保存して全タブを閉じる。

## 〇おわりに
いかがだったでしょうか。この程度できれば、作業効率もりもりで作業できます。（そうです、、、）
これから、わたしもこのコマンドたちを覚えていって、使いこなせるようになりたいと思います。
学習中のみなさん、一緒に頑張りましょう！

参考：https://qiita.com/JpnLavender/items/fabcc79b4ab0d52e1f6d
anacondaにlabelimgインストール方法

windows10,11
物体検出用にSSDの教師データを作るため、無料のlabelimgを導入してみた。


Anacondaのcmdでインストール

①PyQt5のインストール
=
~~~
pip install PyQT5
~~~

②lxmlのインストール
=
~~~
pip install lxml
~~~

④gitのインストール
=
~~~
conda install -c anaconda git
~~~
Conda.orgから調べることもできること
https://anaconda.org/anaconda/git

⑤labelImgのソースコードのダウンロード,インストール
=
~~~
git clone https://github.com/tzutalin/labelImg.git
cd labelImg
pyrcc5 -o libs/resources.py resources.qrc
~~~

⑥最後起動
=
~~~
python labelImg.py
~~~
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3181208/7113b68e-c40b-3801-b3f0-d1a72778203c.png)

画像を読み込み、label作って見るとこんな感じ
![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3181208/a12ebcb8-6f34-7222-0c2a-0cd84a217ee5.png)


ソース元
https://github.com/tzutalin/labelImg

方法２
=
~~~~~~~~
pip install labelImg
~~~~~~~~
これで対象packages: PyQt5-Qt5, PyQt5-sip, lxml, pyqt5, labelImgを全部入れてくれる。
resolve/instantiateの違い





```julia

(@v1.9) pkg> ?instantiate
  instantiate [-v|--verbose]
  instantiate [-v|--verbose] [-m|--manifest]
  instantiate [-v|--verbose] [-p|--project]

  Download all the dependencies for the current project at the version given by the project's manifest. If no manifest exists
  or the --project option is given, resolve and download the dependencies compatible with the project.

  After packages have been installed the project will be precompiled. For more information see pkg> ?precompile.

(@v1.9) pkg> ?resolve
  resolve

  Resolve the project i.e. run package resolution and update the Manifest. This is useful in case the dependencies of
  developed packages have changed causing the current Manifest to be out of sync.

(@v1.9) pkg> ?precompile
  precompile
  precompile pkgs...

  Precompile all or specified dependencies of the project in parallel. The startup.jl file is disabled during precompilation
  unless julia is started with --startup-file=yes.

  Errors will only throw when precompiling the top-level dependencies, given that not all manifest dependencies may be loaded
  by the top-level dependencies on the given system.

  This method is called automatically after any Pkg action that changes the manifest. Any packages that have previously
  errored during precompilation won't be retried in auto mode until they have changed. To disable automatic precompilation set
  the environment variable JULIA_PKG_PRECOMPILE_AUTO=0. To manually control the number of tasks used set the environment
  variable JULIA_NUM_PRECOMPILE_TASKS.

(@v1.9) pkg> 
```
abstract typeとstructの関係についてまとめたもの

abstract typeとstructの関係についてのメモ


以下では、Juliaの抽象型（abstract type）と構造体（struct）を使用して、アザラシ（Azarashi）という抽象型を基本とするいくつかの異なる具象型（Goma, Haiiro, Minami）を定義している。


## 抽象型と具象型の定義

```julia
abstract type Azarashi end

struct Goma<:Azarashi
	nakigoe::String
	weight::Float64
	height::Float64
end

```

GomaはAzarashiとして型注釈されているため、Azarashi型のサブタイプとなります。


## パラメトリックな具象型の定義とコンストラクタの定義


```julia

begin
	struct Haiiro{T<:Real}<:Azarashi
		nakigoe::String
		weight::T
		height::T
		seisokuti::String
	end
	
	function Haiiro(nakigoe::String)
		weight = rand() * 100
		height = rand() * 100
		seisokuti = "Osaka"
		return Haiiro(nakigoe, weight, height, seisokuti)
	end
end
```

Haiiroはパラメトリックな具象型を定義しており、weightとheightはReal型のサブタイプをとることができる。また、ランダムな重さと高さを生成するコンストラクタも定義している。


## 別の具象型の定義

```julia
struct Minami<:Azarashi
	nakigoe::String
	weight::Float64
	height::Float64
end
```


## 多重ディスパッチの関数定義

f関数は、入力の型に応じて異なる振る舞いをする多重ディスパッチの例である。


```julia

begin
	function f(a::Azarashi)
		return a.height
	end
	
	function f(h::Haiiro)
		h.seisokuti
	end
end

begin
	ga = Goma("Kyu", 100, 1000)
	f(ga)
end


begin
	ha = Haiiro("Kyu!")
	f(ha)
end



ha2 = Haiiro("Kyu!", 120, 120, "Wakayama")



begin
	ma = Minami("Kyu!!" , 120, 120)
	f(ma)
end
```


## まとめ
abstract typeは抽象型を定義するために使用され、具象型の基底として機能する。

structは具象型を定義するために使用され、特定の抽象型のサブタイプとして定義されることがある。

Juliaでは、関数は多重ディスパッチをサポートしており、関数の振る舞いは引数の型に依存する。

このコードはJuliaの型システムと多重ディスパッチを利用して、異なる種類のアザラシを表現し、それらの異なる属性に基づいて動作する関数を定義することができる。
todoアプリ編集機能でオブジェクトを作成し、v-modelでnameキーにアクセスしたのに、「TypeError: Cannot read properties of undefined (reading 'name')」とエラーが返ってきてしまう

# 起きたこと

todoアプリの編集機能を作成中に起きたエラー。

各オブジェクト毎に値を制御できるようにした後、更新ボタンを押すと以下のようなエラーとなった。

![todo編集機能エラー.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2597943/22e20ea0-63d9-0722-1c4b-c414f2b0c1c1.gif)


```jsx
TypeError: Cannot read properties of undefined (reading 'name')
```

「nameが定義されてないよ〜」と怒られている。

# 関連のある技術

- Vue3

# 解決したいこと

nameキーにアクセスできるようにして、更新処理をできるようにしたい

# 考えるべきこと

今回、関係してる部分は以下なので、その辺を中心に調べていく。

- V-modelの参照してる値を調べる
    - editModalTargetのキーバリューの値の保持の仕方
- 更新ボタンを押したときに発火している更新処理の関数（handleUpdateTodo）
    - 各行毎の処理が問題ないか調べる

まず、nameキーがないと怒られているので、v-modelで参照してる値を確認してみる。

```jsx
<v-text-field v-model="editModalTarget.todo.name"></v-text-field>
```

特にアクセスの仕方に問題はなさそう。。。

次に、editModalTargetの宣言部分とキーバリューの値の保持の仕方を見てみる。

```jsx
<script setup>
...
const editModalTarget = ref({});
...

const handleOpenModal = (index) => {
  editModalTarget.value = {
    index: index,
    todo: Object.assign({}, todoValues.value[index])
  };

  showDialog.value = true;
}
...
</script>
```

refで空のオブジェクトの宣言を行い、編集ボタンを押したときにhandleOpenModal関数が発火する処理となっている。引数には、各indexの要素番号を受け取っている。

editModalTargetの中では、キーにindexとtodo（各todoのstoreのデータ）が指定されていている。

Object.assignとすることで、コピー元である空オブジェクトに対して、各要素のtodoの値がコピーされる。

ここでの指定の仕方も、特に問題なさそう。

となると、更新ボタンを押したときに発火している更新処理の関数が怪しそう。

```jsx
const handleUpdateTodo = () => {
  const updatedTodoList = [...todoValues.value];
  updatedTodoList.splice(editModalTarget.value.index, 1, editModalTarget.value.todo);
  store.dispatch('updateTodoList', updatedTodoList);

  editModalTarget.value = {};
  showDialog.value = false;
}
```

updatedTodoListで、元のコピーを作成。

コピーしてきたupdatedTodoListをspliceで、editModalTarget.value.todoへ置換してそれを、store側へ渡す。

※余談だが、ここまでの処理に1行ずつconsole.logを挿入して処理を見ていくとどこで、エラーになるかわかる。

結果、上記部分では、エラーが出ないことがわかった！

ということは、editModalTarget.valueの初期化が原因である可能性があり、それについて考えてみたところ…

どうやら、モーダル内で編集を終えた後に、editModalTarget.valueをリセットすることで、編集されたtodoの情報が消されて、nameプロパティがないよと怒られていた！

ということで、その部分を削除して、再度実行…

```jsx
const handleUpdateTodo = () => {
  const updatedTodoList = [...todoValues.value];
  updatedTodoList.splice(editModalTarget.value.index, 1, editModalTarget.value.todo);
  store.dispatch('updateTodoList', updatedTodoList);

  showDialog.value = false;
}
```
![todo編集機能エラー解消.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2597943/d3d2006f-01bb-b1a3-f309-2d9d0fafb96c.gif)


できました！！！

今回の事象が起きた要因としては以下になります。

- editModalTarget.value の初期化

初期化する際は、みなさん気をつけましょ〜

## おまけ

今回は初期化の処理を消すことで、エラーを解消しましたが、そもそも初期化をしないことになるので、それについて問題ないかを調べる必要があります。

```jsx
const handleUpdateTodo = () => {
  const updatedTodoList = [...todoValues.value];
  updatedTodoList.splice(editModalTarget.value.index, 1, editModalTarget.value.todo);
  store.dispatch('updateTodoList', updatedTodoList);

  showDialog.value = false;
}
```

text-fieldに表示される値は、store側で保持されている値になります。

編集ボタンを押して、更新処理をしてからモーダルが閉じられるので、store側の値は常に新しい値を持っている事になり、古い値が表示されることはなさそう。
パッケージリストファイルの場所

インストールパッケージのファイル一覧をメモします。
なぜか忘れたことに見たいタイミングがやってくるのはあるあるなんでしょうか。

```ruby:terminal
cd /var/lib/dpkg/info
cat パケージ名.list
```

参考URL
[第7章 Debian パッケージ管理システムの基礎](https://www.debian.org/doc/manuals/debian-faq/pkg-basics.ja.html)
Javaで「どちらか大きい値または小さい値を取得する」の動作を確認してみた

# 概要

Javaで「どちらか大きい値または小さい値を取得する」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/start/math/index2.html

# 実装

以下のファイルを作成しました。
```JSample2_1.java
class JSample2_1{
  public static void main(String[] args){
    int num1 = 20;
    int num2 = 12;

    System.out.println(Math.max(num1, num2));
    System.out.println(Math.min(num1, num2));
  }
}
```

以下のコマンドを実行しました。
```
$ javac JSample2_1.java 
$ java JSample2_1 
20
12
```

# まとめ
何かの役に立てばと。
GPGで署名できるようにする

# GPGで署名できるようにする
Linux環境(WSL)で確認している。
同じように署名以外の鍵も作成できる。

## 1. 主鍵の作成
以下のコマンドで主鍵を作成する。
```bash
$ gpg --expert --full-gen-key
```

副鍵の管理にしか使わないため(多分？)、Certifyだけできる鍵にする。

## 2. 失効証明書の保管
`~/.gnupg/openpgp-revocs.d/`を開き、失効証明書のファイルを安全な場所に移動させる。

## 3. 副鍵の追加
主鍵のシグネチャを確認する。表示される長い文字列がシグネチャ。
```bash
$ gpg -k --keyid-format LONG --with-keygrip
```

編集モードに入る
```bash
$ gpg --expert --edit-key (主鍵のシグネチャ)
```

プロンプトに入ったらaddkeyと入力する
```bash
gpg> addkey
```

主鍵と同じ感じで副鍵を追加していく。
署名に使う場合はSの付いた副鍵を作る。

## 4. 秘密鍵のエクスポート
主鍵と副鍵を含んだ秘密鍵をエクスポートする。
```bash
$ gpg -a --export-secret-keys
```

この秘密鍵をインポートすることで、後から全ての鍵を復元できる。
秘密鍵は安全な場所に保管しておこう。

## 5. 主鍵の秘密鍵を削除
鍵の一覧を表示して主鍵のkeygripを確認する。
```bash
$ gpg -k --keyid-format LONG --with-keygrip
```

`~/.gnupg/private-keys-v1.d/`を開き、主鍵の秘密鍵のkeyファイルを削除する。
ファイル名は各鍵のkeygripと対応している。

## 6. 公開鍵を配布
公開鍵をエクスポートする。公開鍵は主鍵と副鍵で同じものが使用される。
```bash
$ gpg -a --export
```

## 秘密鍵の一覧表示
ローカルマシンに持っている秘密鍵の一覧を確認できる。
```bash
$ gpg -K --keyid-format LONG --with-keygrip
```

## 鍵の管理や失効証明書の適用を行う
鍵を管理したい時は、主鍵の秘密鍵を復元しないと操作できないことがある。
また、主鍵の秘密鍵が漏洩するなどして主鍵を失効させないといけない場合がある。

その時は保管しておいたファイルをインポートすることで、以下の操作を実施できる。
- 秘密鍵の復元(ファイルに含まれている鍵が全て復元される)
- 主鍵を失効させる
```bash
$ gpg --import (ファイルパス)
```

また、失効証明書はそのままでは使用できなくなっているので、ファイルの中身を確認しよう。
【メモ】なぜパラメトリックタイプを使うのか


### そもそもなぜパラメトリックタイプを使うのか？　
- 型を後から柔軟に指定できるから。

- 例) 最初にintで固定してしまうと、後から型を変更できなくなる。

- ある程度柔軟さを持って、型を指定したいというときに使う。

- 逆に、何も指定しないと型がガバガバすぎて全ての組み合わせの型を通してしまう。

- フィールドの型は具体型にする（型の安定性のため）


```julia
struct MyStruct{T <: Int}
    x::T
    y::Float64
end
```

この場合、xはIntの具体的なサブタイプ（Int64、Int32など）を持つ必要があり、yはFloat64型でなけれならない。


### 色々なストラクトで遊んでみる

```julia 
struct Point{T<:Real}
    x::T　#x,yっていう型はT。TはRealのサブタイプ
    y::T
end

Point{Float32}(0, 0).x |> typeof  #型パラメータのTの部分は後から変更できる。

Point(0f0, 0f0).x |> typeof #もしくは引数で合わせる。f0はfloat32の意味。

Point{Bool}(0, 0).x |> typeof　#boolにすることも可能である。

```


パラメトリックにしておくと、構造体のフィールドがどういう型になるのかを事前に決められる。
つまり、juliaのコンパイラーをヒントを教えるということになる。



```julia
struct Point5{T1, T2}
    x::T1　#x,yを違う型にしたい
    y::T2
end

begin 
    @show Point5(1, -2.0).x |> typeof
    @show Point5(1, -2.0).y |> typeof
end
```


```julia 
struct Point2
    x
    y
end

Point2("goma", 1) #違う型のも通す。
```




### 型指定をした場合のメリット　
型指定をした場合はしない場合に比べて、通常は早くなると言われている。　




### 解析　

```julia 
function d(p::Point, q::Point)
	sd = (p.x - q.x) ^ 2 + (p.y - q.y) ^ 2
	√(sd)
end
```

```julia 
let
	p = Point(1, -1)
	q = Point(1f0, -1f0)
	@show p.x
	@show Base.getproperty(p, :x)
	@code_warntype d(p, q)
end
```


```julia 
function dosome()
	s = 0.
	q = Point(1, 1)
	for _ in 1:100000
		x = rand()
		y = rand()
		p = Point(x, y)
		s += d(p, q)
	end
	s
end	

@benchmark dosome()

@code_warntype dosome()
```





### 初学者向けの便利ツール

```julia
#=
struct Point{Tx, Ty}
	x::Tx
	y::Ty
	function Point(x::Tx, y::Ty) where {Tx, Ty}
          return new{Tx, Ty}(x, y)
    end
end
=#
# ↑と同じ
@concrete struct Point
	x
	y
end
```

```julia
let
	p = Point(1, -1)
	@show typeof(p)
	q = Point(false, false)
	@show q.y typeof(q)
	@show Base.getproperty(p, :x)
end

function goma(p::Point{T, T}, q::Point{T, T}) where T<:Real
	p.x + q.x + p.y + q.y
end

```



メモ



次のように、Juliaで構造体のフィールドや配列などのコンテナ系の要素型を具体型で指定することができます。

```julia
struct MyStruct{T}
    field::T
end

struct MyArray{T, N}
    array::Array{T, N}
end

struct_1 = MyStruct{Int}(10)
struct_2 = MyStruct{Float64}(3.14)

array_1 = MyArray{Int, 1}(1:10)
array_2 = MyArray{Float64, 2}(rand(2, 2))
```


```julia
abstract type MyAbstractType end

struct MyStruct{T <: MyAbstractType}
    field::T
end

struct MyArray{T <: MyAbstractType, N}
    array::Array{T, N}
end

struct MyConcreteType1 <: MyAbstractType
    value::Int
end

struct MyConcreteType2 <: MyAbstractType
    value::Float64
end

struct_1 = MyStruct{MyConcreteType1}(MyConcreteType1(10))
struct_2 = MyStruct{MyConcreteType2}(MyConcreteType2(3.14))

array_1 = MyArray{MyConcreteType1, 1}(MyConcreteType1.(1:10))
array_2 = MyArray{MyConcreteType2, 2}(MyConcreteType2.(rand(2, 2)))
```





```julia
using BenchmarkTools

struct Point
    x
    y
end

function d(p::Point)
    p.x ^2 + p.y ^2
end

function dosome()
    s = 0.
    for _ in 1:10000
        x = rand()
        y = rand()
        p = Point(x, y)
        s += d(p)
    end
    s
end
```
EXCELのVBAでR1C1形式のアドレスをA1形式に変換する方法

WorksheetオブジェクトのEvaluateメソッドにアドレスを与えることでRangeオブジェクトが取得できます
このことを応用します
```vb
    Dim r As Range
    Set r = Evaluate("=R1C1:R3C4")
```
ただし、R1C1形式のアドレスを与えるには、アドレスの表示形式をR1C1形式にしておく必要があります

```vb
Function R1C1_To_A1(R1C1Address As String) As String
    Application.ReferenceStyle = xlR1C1 '表示形式をR1C1形式に変更
    R1C1_To_A1 = Evaluate("=" & R1C1Address).Address(0, 0) '行列ともに相対参照形式
    Application.ReferenceStyle = xlA1 '表示形式をA1形式に戻す
End Function

Function A1_To_R1C1(A1Address As String) As String
    A1_To_R1C1 = Range(A1Address).Address(, , xlR1C1) '行列ともに絶対参照形式
End Function

Sub Test()
    Debug.Print R1C1_To_A1("R1C1:R3C4")
    Debug.Print A1_To_R1C1("A1:D3")
End Sub
```
実行結果
``` A1:D3 ```
``` R1C1:R3C4 ```
リモートデスクトップで音が鳴らなくなる現象を一時的に直す

## Macでリモートデスクトップを使用していたら、時々音が鳴らなくなっている
再起動すれば直るけど、WindowsAudioのサービスを再起動。
サービスからWindowsAudioを再起動もできます。

```Batch:RestartWindowsAudio.bat
@echo off

net stop AudioSrv
net start AudioSrv
```

管理者権限が必要です。
多分、副作用はないと思いたいのですが、自己の判断で。
Mac の PowerShell で Exchange Online に接続してメールが有効なセキュリティグループを作成してみた

大量にメールが有効なセキュリティグループを作成するわけではないので、Exchange 管理センターからポチポチやれば済むのですが、訳あって万が一管理センターに入れない場合に備えて、CLI で作成する方法も準備しておこうかと思います。もともと CLI が好きなのもありますが、GUI で人間が操作するとミスがおきやすいものなので、普段から再現性の高い CLI のコードを残しておきたくなります。そこで今回は、Mac の PowerShell で Exchange Online に接続してメールが有効なセキュリティグループを作成してみました。

## Powershell のバージョン確認

```bash
% pwsh --version
PowerShell 7.3.5

# Powershell に入る
% pwsh
```

## PowerShell での操作例


```powershell
# Exchange Online PowerShell モジュールをインストール
Install-Module -Name ExchangeOnlineManagement -Scope CurrentUser

# Exchange Online PowerShell モジュールをインポート
Import-Module ExchangeOnlineManagement

# インストールされているモジュールのバージョン情報を確認
Get-Module ExchangeOnlineManagement | Select-Object Version

Version
-------
3.3.0

# 例えば Azure CLI のユーザー情報からグローバル管理者を取得
$myUpn = $(az account show --query user.name --output tsv)

# テナントのプライマリドメインを設定
$primaryDomain = "example.com"

# グローバル管理者か Exchange 管理者で Exchange Online に接続
Connect-ExchangeOnline -UserPrincipalName $myUpn

# テナントを指定して Exchange Online に接続する場合
Connect-ExchangeOnline -UserPrincipalName $myUpn `
  -DelegatedOrganization $primaryDomain

# メールが有効なセキュリティグループを作成
New-DistributionGroup `
  -Name テストグループ1 `
  -PrimarySmtpAddress test-group1@$primaryDomain `
  -Type Security

# もう一つメールが有効なセキュリティグループを作成
New-DistributionGroup `
  -Name テストグループ2 `
  -PrimarySmtpAddress test-group2@$primaryDomain `
  -Type Security

# 一つ目のセキュリティグループに自分自身をメンバーとして追加
Add-DistributionGroupMember `
  -Identity test-group1@$primaryDomain `
  -Member $myUpn

# 一つ目のセキュリティグループに二つ目ののセキュリティグループを追加
Add-DistributionGroupMember `
  -Identity test-group1@$primaryDomain `
  -Member test-group2@$primaryDomain

# 二つ目のセキュリティグループを削除
Remove-DistributionGroup `
  -Identity test-group2@$primaryDomain

# 一つ目のセキュリティグループを削除
Remove-DistributionGroup `
  -Identity test-group1@$primaryDomain

# Exchange Online から切断
Disconnect-ExchangeOnline
```

## 参考

https://learn.microsoft.com/ja-jp/powershell/exchange/exchange-online-powershell-v2?view=exchange-ps#install-the-exchange-online-powershell-module

https://learn.microsoft.com/ja-jp/powershell/module/exchange/new-distributiongroup?view=exchange-ps

https://learn.microsoft.com/ja-jp/powershell/module/exchange/add-distributiongroupmember?view=exchange-ps

https://learn.microsoft.com/ja-jp/powershell/module/exchange/remove-distributiongroup?view=exchange-ps
AtCoder ABC284-A

AtCodeのビギナー用A問題をひたすら解いてます。
簡単なのでモチベーションあがります。
こうしたらOKだったよっていうのを載せていきます！
# AtCoder Beginner Contest 284
https://atcoder.jp/contests/abc284/tasks/abc284_a

```
n=int(input())  #入力を数値に
lst=[]          #空のリストを作る
for i in range(n):#N回繰り返し
    lst.append(input()) #リストに入力した文字を入れる
lst.reverse()#並べ替え（lst.reverse()を直接printしてはいけない→Noneが返るから）
for char in lst:
    print(char)
```
暗号方式

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/92fd0b6b-88a3-deb1-8b59-9ad1b8bfac27.png)
１：公開鍵暗号方式
　RSA、DSA（離散対象数暗号）、ECDSA(楕円曲線暗号)などの方式があります。RSAは、素因数分解を行うことが困難であるという点を利用した方式です。守秘とディジタル署名の量の意に利用できます。DSAとEDCSAはディジタル署名専用の方式です。ECDSAで用いる楕円曲線暗号は、RSAやDSAよりも短い鍵長でで同程度の強度（攻撃者が、秘密鍵を演算処理によって入手することに対する耐性の強さ）が実現できます。現時点（2030年まで）では、RSAや DSAでは２０４８ビット以上の鍵長の利用が推奨されています。

　鍵長が短いと、署名を作成したり、検証したりする時間を短くできます。よって、RSAで署名を作成するよりも、ECDSAで署名を作成する方が良いと考えられています。

２：ハイブリッド暗号方式
　ハイブリッド暗号方式は、共通鍵暗号方式と公開鍵暗号方式の利用を組み合わせた方式です。セッション鍵暗号方式とも呼ばれます。電子メールの暗号化（S／MIME）をはじめとして、さまざまな場面で利用されています。暗号化/復号の処理を高速に行うことができ、事前に鍵を取り決めておかなくても暗号通信が可能です。
例：
①Aは、平文（メッセージ文）を暗号化するために自分の共通鍵を作ります。一般的には、乱数を元にして作ります。この共通鍵をセッション鍵と呼びます。
②Aは、Bにセッション鍵を伝えます。そのまま伝えては、第三者にわかっていますから、セッション鍵をBを公開鍵を暗号化してから送ります。
③Bは,Bの秘密鍵で復号し、セッション鍵を入手します。
④Aは、平文をセッション鍵で暗号化してBに送ります。
⑤Bは、セッション鍵で復号して平文を入手します。

　ハイブリッド暗号方式では、ヘイブンは共通鍵暗号方式を用いて暗号化します。一方で、セッション鍵は公開鍵暗号方式を用いて暗号化します。平文はサイズが大きいいからですから、高速に暗号化/復号できる共通鍵暗号方式を使おうという趣旨です。一方で、共通鍵暗号方式しか使わないと、相手と事前に鍵を取り決めなくてはならず、面倒です。そこで、公開鍵暗号方式も利用して、セッション鍵を暗号化して相手に送り、事前に鍵を取り決めの手間を省くのです。
[リサーチ・メモ] Mockを破棄する

## 背景
junitでテストを実施した際に、テスト対象外のAPIにもMockが影響していた。その為、対象テスト完了後にtearDown()でMockを破棄する。


## 実施方法
BeforeでMockのインスタンスを生成
```
@Before
  static void discardMock() throws Exception {
    MockUp<fuga> hogeMock = new MockUp<fuga>() {
      @Mock
      String piyo() {
        return null;
      }
    };
  }
```
AfterAllにtearDown()を記載し、テストクラスの最後に特定のMockを破棄する
```
@AfterAll
  static void discardMock() throws Exception {
    hogeMock.tearDown();
  }
```

全てのMockを破棄する場合は、下記の記述で実現できる
```
@AfterAll
public static void clearMocks() {
    Mockito.framework().clearInlineMocks();
}
```
フロントエンド開発の変遷⑤ Reactの登場とコンポーネント指向・状態管理

前回はフロントエンドライブラリの乱立時代について整理しました。
今回はこのフロントエンドライブラリ乱立時代の中で登場したReactについて整理しています。

前回はこちら

https://qiita.com/yusuke2310/items/d6851137b00c9df42fc4


---

:::note
Reactは２０１３年にFacebookが公開したUIライブラリです。現在最も人気のあるフロントエンドライブラリです。
モダンWebアプリケーション開発はフロントエンドのコードの記述量が増大し、可読性が悪く、メンテナンスが困難になりがち。Reactはこのような問題を回避し、効率的に開発を進めるためにコンポーネントや状態管理などの設計をベースとした思想を取り込んでいる
:::

##### Reactの特徴
* 仮想DOM
* 宣言的UI
* 単一方向のデータの受け渡し
* コンポーネント指向・関数コンポーネント
* Fluxアーキテクチャとの親和性

Reactの特に画期的な点は仮想DOMとステート管理の設計です。仮想DOMは直接ブラウザの持つDOMのAPIを操作するのではなく、ノードが変更があった場合、変更前後の仮想DOMを比較して変更箇所を特定し、必要に応じてまとめて実際のDOMに変更を適用するという発想から生まれました。


パフォーマンスを向上させることも可能で、テストも容易になり、ブラウザの実装に依存しない形でDOMを組み立てられるため、のちにサーバーサイドでのコンポーネントレンダリングなどに応用されます。

##### 大規模向け状態管理Flux
:::note
コンポーネント指向でアプリケーションの開発を進め、複雑化していくと、状態（ステート）の管理がより重要になります。特に状態管理が複雑になると、大規模向け状態管理の手段が必要です。
:::

2014年にFacebookはFluxアプリケーションアーキテクチャを提唱します。Fluxを使うことでデータの流れを単一方向に限定し、状態管理をよりわかりやすくできます。

アプリケーションの表示を担うViewで必要となる状態の取得はStoreから行う一方で、状態の更新はActionというデータをDispatcherに渡すことで行うというように、取得と更新の役割が分担されます。

Fluxは複雑化するフロントエンド開発に大きく影響を与えました。現在の状態管理ライブラリ、フレームワークの多くはFluxの考えを小なり大なり取り込んでいます。現在はFluxを発展的に継承したReduxというライブラリが人気です。

Reactが登場してから数年経ち今もなお人気で進化を遂げる理由として、仮想DOMの発明だけではなく、 Fluxのような「データの流れ」に関する提唱も画期的であったことが挙げられます。
Nano Piをいじる（その２）

# 特定のポートのみ通過
その２では、特定のポートのみ通過させる設定を行ったときのメモ。ここでは、TCPポート80および443のみとおす。

## 設定
### 全般
ファイアウォールの一般設定のデフォルトは下記となっている。
![デフォルトファイアウォールゾーン１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/63cf7f1b-01b4-397b-287e-c9450ed572bb.png)
転送を「拒否」に変更する。
![Firewall一般設定のコピー.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/dddbea39-e90d-6ce2-7909-9545d63be2f6.jpeg)

### ゾーン”lan”
ゾーンのデフォルトは下記となっている。
![Default Firewall Zone.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/21a2d781-4126-cebf-fdd7-d66374294a12.png)
”lan”の変更を行う（編集をクリック）。変更前、「宛先ゾーンへの転送を許可する」として、”wan”が指定されている。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/13a58db7-9d08-61b9-9bbe-b911590fdf8d.jpeg", width=80%>
この”wan”を削除する。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/d12c210f-cb1f-ae6e-4c9a-8496b2ce9113.jpeg", width=80%>
保存すると下記となる。
![ゾーンリスト変更後のコピー.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/e82f3f3b-7b2c-8e10-8251-3a85d61e088b.jpeg)
なお、「一般設定：転送」を「許可」のまま、「ゾーン”lan”：転送」を「拒否」にしても、うまく動作せず、、であった。

### ポート80および443の有効化
ポート80および443のためのトラフィックルール（転送：許可）を新規作成。送信元ゾーンは”lan”、宛先ゾーンは”wan”となる。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/31522cb2-5a19-6ee0-2d0e-d3b588ddb67c.jpeg", width=80%>
ついでに、ICMPも追加、ゾーン指定は同様。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/207b8aed-4eca-2348-5601-9f20bc34abc7.jpeg", width=80%>
トラフィックルールは下記となる。
![トラフィックルール.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/75653127-bd4f-1601-9769-720d3b168eb2.jpeg)
![トラフィックルール2のコピー.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/63acfb5b-0e46-594d-73a1-75f77778f7ad.jpeg)

これで完成＆動作OK（パケットデータは省略）。

EOF
【CSS】animationのtransformを指定しているとき、100%後にちらつく不具合の対処法【スマホ】

## 前書き

PCでは正常に動くのに対し、iPhoneのChromeでタイトルの現象が発生したのでその対処法を書きます。

## バグったコード

https://qiita.com/nissuk/items/7d5545a9f6177ff965dc

```css
@keyframes marquee {
    0% { left: 100%; transform: translate(0); }
  100% { left: 0; transform: translate(-100%); }
}
```

## 対処法

```css
@keyframes marquee {
    0% { left: 100%; transform: translate(0); color: black; }
   90% { left: 0; transform: translate(-100%); color: black; }
  100% { left: 0; transform: translate(-100%); color: transparent; }
}
```

100%後のCSSがtranslate(0)で再描画されているっぽいので色を消して対応しました。
多少の間隔（今回だと10%）がないと相変わらずちらつきました。はあ…。

## 効果がなかったやつ

ググるとでてくる
・perspectiveを指定する
・backface-visibility:hiddenにする
みたいな対処法は全く効果がありませんでした。

## チラ裏

特定の端末のためにこういうハックを仕込むの嫌い。
Ubersuggestで画面が表示されないときの解決策


Ubersuggestで、なかなか画面が表示されないということがあったので、その解決策を書いておきます。

環境は、Windows10です。


## 問題となったUbersuggestのトラブル

Ubersuggestにアクセスした際、以下のような状態がずっと、つづいていました。

右側の円グラフみたいなのが、ずっとグルグルしている状態。

![2023-09-16_02h22_40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2799113/f8e9dc06-465a-9df3-8e39-a96c53265d69.png)


## Google Chromeの設定を変更することで解決した。

問題は、Google Chromeの設定にある「メモリセーバー」を、オンに変更することで解決しました。

実施した手順は以下です。

1.Google Chromeの右上にある設定ボタン（点が縦に3つ並んでいるボタン）をクリック
2.表示されたメニューから、設定をクリック
3.左のメニューから、パフォーマンスをクリック
4.メモリセーバーをオンに変更
5.Ubersuggestのページを何度か更新ボタンをクリックして、更新
6.Ubersuggestの画面が表示される

以下のように、正しく表示されて調べたいサイトのURLを入力できるようになりました。

![2023-09-16_02h45_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2799113/f30636d3-e9ba-a1ad-e229-a2cbcf0fdfd0.png)

## Ubersuggestで画面が表示されないときの解決策（まとめ）

私の環境で起こったUbersuggestで画面が表示されないという問題の解決策を説明しました。


メモリセーバーをオンに変更したことで解決したということは、なにか他の原因でメモリーが不足しているのかもしれません。

そのため、根本的な解決策にはなっていないかもしれませんが、おなじような問題で困っている人もいるかもしれません。

そういう方の参考に、少しでもなれば、幸いです。


おしまい。
FuelPHPのコントローラーでnamespaceを設定すると"Cannot redeclare class"とコンパイルエラーが出る

<h1>前提</h1>

現在FuelPHPを使って開発しており、その中でコントローラーにnamespaceを設定しても全て"Cannot redeclare class"の一点張りで詰まってめちゃ時間食ったので備忘録に。

<h2>環境</h2>

FuelPHP：version1.9

<h2>解決方法</h2>

/app/config/config.php内に
```php:/app/config/config.php
'controller_prefix' => 'Controller\\',
```

この１文を加えるだけで解決しました！

<h2>原因</h2>
原因を調べてみても知識がないため、あまり理解できませんでした...(sorry)
<br>下はchatGPT原文ママです。有識者の方、原因についてご教示いただけると助かります🤦‍♂️

>FuelPHPでは、デフォルトでコントローラーのクラス名を解決する際、名前空間（namespace）を含める必要があります。しかし、設定ファイルで「'controller_prefix' => 'Controller\'」という設定を行うことで、名前空間のプレフィックスを指定することができます。このプレフィックスを指定することで、FuelPHPはコントローラーのクラス名を正しく解決できるようになります。
具体的には、例えば「Controller_Home」というコントローラーを呼び出す場合、プレフィックスを含めた「Controller\Home」の形式でクラス名を解決するようになります。したがって、コントローラーのクラス名とファイル名、そして名前空間の設定が整合していない場合でも、この設定により正しくクラスを解決することができます。
この設定を追加することで、FuelPHPのオートローディングがコントローラークラスを見つける際に正しい名前空間を考慮するようになり、クラス名の重複や名前空間の不整合に起因するエラーが解消されたと考えられます。

閲覧いただきありがとうございました！
【個人開発】【iOS】目標達成をサポートするアプリ「DrawGoal」をリリースしました！

# 前置き
こんにちは、個人開発が趣味のりょうやです。
最近開発した「DrawGoal」というアプリを紹介します。

https://apps.apple.com/us/app/drawgoal-%E7%9B%AE%E6%A8%99%E9%81%94%E6%88%90%E6%94%AF%E6%8F%B4%E3%82%A2%E3%83%97%E3%83%AA/id6451417773

# どんなアプリか

「DrawGoal」は目標達成をサポートするアプリケーションです。自らの目標を設定し、その達成に向けての日々の進捗を記録することができます。シンプルな操作性で、誰でも簡単に利用することができます。特に、目標を持っているものの、その達成に向けての具体的なアクションや進捗の管理が難しいと感じている人にとって、非常に役立つツールになると思っています。

# 何故このアプリを開発したか

多くの人は、物事を進める際に目標を立てて行動します。しかし、目標に向かって進む途中での進捗をきちんと記録する人は少ないのではないでしょうか。私も計画的に物事を進めるのは得意ではなく、ついつい突っ走ってしまうことが多いです汗

このような背景から、DrawGoalの開発を始めました。目標達成までの進捗をきちんと記録することで、モチベーションの向上や問題点の発見が容易になります。また、進捗を記録することで計画性の重要性を実感できると考えました。

私もDrawGoalを使い始めてから、物事をはじめる前に計画を立てる習慣が身につきました。

# 使い方
## 目標設定

「達成日」、「中間目標」、「ご褒美」を設定し、自分の目標を明確にします。中間目標やご褒美を設定することで、目標達成へのモチベーションが高まります。

![エンジニア同士で交流できる マッチングサービス (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597913/e9b6fd45-a24e-58f7-32e4-9408fff2b29b.png)

# カレンダー機能

中間目標の進捗がある日はカレンダー上にポインタが表示されます。進捗状況が一目で確認できます。さらに、中間目標と最終目標の達成予定日は色で区別されます。

# 進捗の可視化

日々の進捗は折れ線グラフで視覚的に確認できます。また、中間目標の進捗率は円形の進捗バーで一目瞭然です。

![エンジニア同士で交流できる マッチングサービス (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597913/0a9010f3-2371-0332-e7c8-4f18cfd7725f.png)

# 通知機能

中間目標や最終目標の達成時にはアラートが表示されます。これにより、目標達成の瞬間を見逃すことはありません。

# 最後に

このアプリを通じて、皆さんの目標達成を心から応援しています。
日本語プログラミング言語が必要な理由

この記事は、プロデル公式ブログに掲載したコラムを再投稿したものです。

https://produ.irelang.jp/blog/2017/03/105/

# 日本語でプログラムを書きたい

多くのプログラミング言語では、英単語や記号の羅列によって定義や動作を記述する言語仕様です。ただ日本語で読み書きし話し考える日本人にとって、義務教育の中で英語を学ぶとは言え、英単語を扱うことは日本語を扱うよりも難しいように思います。多くの日本人は日本語だけで物事を理解して考えているからです。

そういった中でソフトを作るプログラミングという作業でも、「英単語を使わずに日本語を使いたい」と考えることは自然なことのように思います。

ところが実際は最初に述べたような英単語主体のプログラミング言語が主流で、日本語を話すプログラマでも多くは英単語主体のプログラミング言語を使っています。そこには既に習得したプログラミング言語から移行してまで日本語でプログラムを書きたいとは思わない。という背景もあるのかと思います。

そこで、日本語プログラミング言語が必要な理由を挙げてみることにしました。

### 日本語表記で名前を付けられる

多くのプログラマは何かアプリを作るためにプログラミングします。そのアプリの対象物が日本人を対象として日本語で名付けられているものであれば、日本語のままプログラムに書くことができれば便利です。

英単語主流のプログラミング言語では、日本語で名付けられたものを、わざわざ英単語に置き換えて、プログラムしています。この時に脳内で翻訳作業をしています。

日本語で名付けられたものに日本語を使ってプログラミングできれば、余計な変換をせずにプログラミングで必要なロジックの記述に集中できます。

### 識別子に日本語が使えるだけでは足りない

JavaやC#をはじめとして、現在の多くのプログラミング言語処理系ではソースコードにUnicodeなど日本語を扱える文字コードに対応しています。

また文字列定数に限らず、プログラム内の変数名や関数などの識別子にも日本語を使うこともできます。実際にVBAで日本語を使ってプログラムを書いているといった例も見かけます。

しかし、このような場合でも、ifやfunctionなど基本構文で使われるキーワードは、英単語のままです。またObjectやStringなどの型名や、printやcloseといった標準ライブラリの関数名も英単語表記のままです。

日本語プログラミング言語は、キーワードやライブラリ群も含めて、すべて日本語で定義され用意されているので、ソースコードに一貫して日本語表記を使うことができます。

### 語順を日本語文と同じように書ける

日本語プログラミング言語は、プログラム文でいわゆる「てにをは」の助詞を使って日本語の語順でプログラム文を書けることが特徴であり、魅力の一つです。

関数呼び出しではパラメータの関係を式と助詞を紐付けることで記述します。これはAdaやVBAなどにある名前付き引数の仕組みと似ています。助詞を使って引数の関係を明確にし、また日本語としても読みやすいプログラムとなるように言語仕様を工夫しています。

またオブジェクト指向言語にある「.」や「->」などは、記号に頼らずに「の」や他の助詞を用いて日本語の字句で表現しています。

このようにプログラミング言語の機能を、日本語文に当てはめて日本語風に書けるように文法を定めています。これは、プログラムを読めば素直にプログラムの動作を理解できるようにすることを意図しています。日本語プログラミング言語の実装によって表記は異なりますが、この点は、どの日本語プログラミング言語でも共通の考え方です。

## 日本語プログラミング言語不要論

「日本語でプログラムを書く」ということに否定的な人もいることは知っています。そのように思う人は、おそらく「記号や数式で書き下すことだけがプログラミングだ」と信じ込んでしまっているからと想像してます。

ひとつ言いたいのは、日本語プログラミング言語であったとしても「プログラミング言語」であることには変わりなく、コンピュータを動かすロジックを書くための手段に変わりありません。例えばRubyが好きかC#やVBAが好きか、手続き型が便利か、関数型やリスト型が便利か、といった違いと同じです。

それぞれプログラミング環境に求める物が異なる以上、日本人のプログラマ万人に受け入れられるものではないと考えています。「日本人であれば皆日本語プログラミングをすべきだ」と主張するつもりは全くありません。日本語プログラミング言語を必要と思う人が使えば良いだけの話しです。

ただ、”自分には必要ない”と思うだけに留まらず、声を大きくして「日本語プログラミング言語は必要ない」と言い出す人がいくらかいることは知っています。このような人は、なぜ日本語プログラミング言語の取り組みを話題に挙げて、わざわざ必要ないと主張するのでしょうか。素直に言って不思議です。(例えば、自分はパプリカを食べないからと言って、農家が育てたパプリカを話題に取り上げて「パプリカは必要か？」と言いますでしょうか、普通…)

日本語プログラミング言語を便利と思って利用しているプログラマがいる事実を見れば、日本語プログラミング言語が必要だ不要だと議論すること自体が滑稽です(((

## 脱初心者向けプログラミング言語

これまで日本語プログラミング言語は、日本語だからプログラミング初心者に優しい、プログラミング教育に向いているということをメリットとして主張してきたところがありました。実際、学術的な世界では、日本語を使ったプログラミング学習環境を提案し、教育現場で実際に活用する研究もあり、その成果が報告されています。

一方で最近では、日本語で書かれたブロック図形を画面上に貼り付けて組み合わせることで、マウスやタッチ操作でロジックを作れるプログラミング環境も提供されています。PCの性能が向上した今、入力誤りの可能性があるテキスト形式で日本語プログラムを書くことが必ずしも初心者に優しいとは限らなくなりました。

改めて考えてみると、先に挙げたような日本語プログラミング言語の良さは、実用的なプログラミングでこそ意味があるのように思います。日本語プログラミング言語の良さを活かせる環境を持ち合わせた実用的な日本語プログラミング言語が本当は必要なのではないでしょうか。

また掲示板やブログなどからプログラムをコピー＆ペーストしたり、バージョン管理システムでコードを共有したり差分を比較したりできる点は、テキスト形式のプログラミング言語の良さであり、実用的なプログラミングであればこそ重要なように思います。

## プロデルはどうか

プロデルの目指す日本語プログラミング言語は、実用的に使えるプログラミング言語です。プロデルが日本語プログラミング言語の本当のメリットを活かせるだけの力を持っているとは言えないかもしれません。本稿では挙げませんでしたが、日本語プログラミング言語そのものにもデメリットはあります。デメリットを少しでも克服して、メリットを大いに活かした日本語プログラミング言語を作り上げることを目標にして、今後も改良を続けられたらと思います。
Thymeleaf + Springboot + Mybatis + MySQL + VSCodeーRESTful API(@RestController)

### ＠Controllerを使って、画面遷移を実現する。
##### RESTful APIとは
　RESTの原則に則って構築されたWebシステムのHTTPでの呼び出しインターフェースのこと。
　　　　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480807/6dbb3c37-9db8-2674-1aa1-f6a730ae1575.png)

---
##### RESTとは

　REpresentational State Transferの略で、分散型システムにおける複数のソフトウェアを連携させるのに適した設計原則の集合、考え方のこと。Roy Fieldingが2000年に提唱した。

---
　※以下のような流れでクライアントのリクエストからJson形式のデータを返却します。
　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480807/7600d6ce-5bba-1bcd-ab3f-2b026a0ad23f.png)

---
■流れ説明
　・クライアントがWeb Serviceにリクエストを送ります。
　・MappingのHandlerとそのTypeをサーチするDispatcherServletにリクエストをインターセプトします。
　・RestControllerはリクエストの処理を行い、データを返却します。

---
### 検証
##### Controllerクラスを作る
　1\. Javaクラスファイル作成
　　プロジェクトの下記ディレクトリーの配下に「<strong>TestRestAPIController.java</strong>」を作成する。<strong>src/main/java/jp/co/picasoft/training/api/controller</strong>
　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480807/cef5a079-997e-56e9-1216-32844c8446d2.png)

---
　2\. Javaクラスファイルの編集
　１で作成されたTestRestAPIController.javaに下記ソースを貼り付けて。
　<font color=red>※javaファイル中のパッケージ情報を変更しないでください。</font>
```java:TestRestAPIController.java
import java.util.HashMap;
import java.util.Map;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class TestRestAPIController {
    
    @GetMapping("/greeting")
    public Map<String, Object> greeting() {
        Map<String, Object>  m = new HashMap<>();
        m.put("code", 0);
        m.put("messages", new String[]{"Good luck!"});
        Map<String, Object>  data = new HashMap<>();
        data.put("id", 1);
        data.put("name", "田中陽子");
        m.put("data", data);
        return m;
    }
}
```

---
##### 動作確認
　1\. アプリケーション起動
　Thymeleaf + Springboot + Mybatis + MySQL + VSCodeー画面遷移の[「1. アプリケーション起動」](https://qiita.com/training_zhang/items/6208f5b28f0673f7ac9e#%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D)を参照してください。

---
　2\. ブラウザで動作確認
ブラウザを起動して、アドレスバーに「[http://localhost:8080/api/greeting](http://localhost:8080/api/greeting)」を入力して、「Enter」キーをクリックして、先作成したルーティングに対するRestControllerで、作成したMapを自動的にJSONに変更して、返却されることを確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480807/50029876-e16b-98ba-3b3e-62e781260548.png)

---
### 参照
[Spring MVC Framework and REST](https://senthilsivam.wordpress.com/2016/11/03/spring-mvc-framework-and-rest/)
ようつべ体験記10

[前回](https://qiita.com/matsukatsu/items/4eaa878457fdf71cc59a)

#### ターゲットに受けるもの

ちょっとブログの投稿があいてしまいました。
動画投稿はさほど時間がかからないので続けられていたのですが、ブログは時間がかかるのでトラブルがあるとどうしても中断せざるを得なくなります。

> 基本的には 日本人男性、25-34歳 をイメージして作成すれば

前回、このように言っておきながらこの人たちに受けるものが何なのか、とくに答えを出していませんでした。
この世代の旅行先として良い資料があるのでしょうか...
面倒くさくなってきたので Google の AI に聞いてみました。

![スクリーンショット 2023-09-15 23.33.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/0e78d6eb-1c5d-d0ec-7f47-08c6acce2e64.png)

どこから引っ張ってきた情報かわからないですが、なんとなくそれっぽいです。
メインターゲットにしている日本人男性25歳から34歳は人間ですが、その人にインプレッションするかどうかを決めるのは AI なので、下手に考えるより AI に言われるがままの方が良いかもしれません。


そして前回のブログ投稿から1週が経ったので、1週分の動画投稿も済んでいます。
*13* と *14* の動画です。
![チャンネルアナリティクス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/0060c8d1-43d6-1ad0-a22e-614e9854ddf7.png)
*14* はヨーロッパなので `6.西ヨーロッパ2` のように手堅く伸びて欲しかったのですが、いまいち初動が良くないです。
まだ投稿して1日だし悪い感じではないですが、イマイチな感じです。
西ヨーロッパならなんでも良いという訳でもなさそうです。
次回のヨーロッパは AI の指示に従ってみようと思います。


#### 前回の悩み

> もう僕はヨーロッパの動画をひたすら作り続けるしかないのでしょうか

1週間考えていましたが、多分そうなんだろうという気がします。
ちょうどこの1週間で若干バランスが変わってきたのですが、僕のチャンネルはリピーターよりも新しい視聴者がかなり多い傾向があります。
![コンテンツ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/2698827f-b2b8-a312-e7b4-f6e9960aa5f4.png)

こういった特徴を公式ヘルプではこのように説明しています。
[リピーターよりも新しい視聴者の数が多い場合、視聴者はチャンネル全体のテーマよりも特定のトピックや動画に高い関心を持っていると考えられます。](https://support.google.com/youtube/answer/13615784?sjid=4716296336156556938-AP#:~:text=%E3%83%AA%E3%83%94%E3%83%BC%E3%82%BF%E3%83%BC%E3%82%88%E3%82%8A%E3%82%82%E6%96%B0%E3%81%97%E3%81%84%E8%A6%96%E8%81%B4%E8%80%85%E3%81%AE%E6%95%B0%E3%81%8C%E5%A4%9A%E3%81%84%E5%A0%B4%E5%90%88%E3%80%81%E8%A6%96%E8%81%B4%E8%80%85%E3%81%AF%E3%83%81%E3%83%A3%E3%83%B3%E3%83%8D%E3%83%AB%E5%85%A8%E4%BD%93%E3%81%AE%E3%83%86%E3%83%BC%E3%83%9E%E3%82%88%E3%82%8A%E3%82%82%E7%89%B9%E5%AE%9A%E3%81%AE%E3%83%88%E3%83%94%E3%83%83%E3%82%AF%E3%82%84%E5%8B%95%E7%94%BB%E3%81%AB%E9%AB%98%E3%81%84%E9%96%A2%E5%BF%83%E3%82%92%E6%8C%81%E3%81%A3%E3%81%A6%E3%81%84%E3%82%8B%E3%81%A8%E8%80%83%E3%81%88%E3%82%89%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82)

チャンネルとしてはテーマが散漫になっていて、特定の動画のファンは得られてもチャンネルのファンが得られにくい状態なのでしょう。
動画ごとに視聴者の特徴がバラバラなのもそれを示唆しています。
となるとチャンネル登録者数が増えません。

ただ、ヨーロッパだけを公開した場合、今のスタイルで続けると2〜3ヶ月でネタが尽きそうです。
楽に長く続ける事を考えると、やはりヨーロッパだけ公開する方針はとれません。
それに、ヨーロッパだけを公開して得たチャンネル登録者は、ネタが尽きてヨーロッパ以外にシフトした場合に失望して離脱する可能性もありそうです。

消極的な感じがしますが、結局ヨーロッパとそれ以外の地域を交互に出すという方針は維持する必要がありそうです。
方針は維持するのですが、消極的な感じではなく、あえてそうしてるんだよと言い換えたいです。
いい考えはないだろうか...

動画投稿を始めて、特定の週を除いて1週間に2回投稿しています。
この1週間に2回の投稿が、なんとなく昔のシングルCDみたいだなーという気がしていました。
A面とB面の2曲で1シングルCDという組み合わせですね。
これにはどういう意味があったのでしょう。

note でまとめておられる方がいました。
[A面とB面の性質をよく知った上で両方を効果的に使って勝負する話](https://note.com/boo_ooi/n/n824d040ceaf2)

A面は売るための曲です。その分、好きに作れません。
ミスチルで例えると、`innocent world` とか `CROSS ROAD` の事です。
B面は好きに作ってよいです。でも、その好きに作ったものにこそ出る作家性のような部分に惹かれるファンがいます。
ミスチルで例えると、`花はどこへ行った` や `and I close to you` といった曲です。知りません。

A面が好きなファンもB面が好きなファンもミスチルのファンですが、少し性質が違うのでしょう。
両方のファンがいるからこそ、ミスチルには膨大なファンがいたのだろうし、両方の曲をリリースできる事がバンドのモチベーションにも繋がっていたのかもしれません。

感じていたジレンマを解消するのに良い考えな気がします。
例にミスチルを出した事で恥ずかしさがありますが、僕もそういう事にしてみます。

[次回](https://qiita.com/matsukatsu/items/910e9418844d5a29074b)