OmniAICreator/Qiita-1.07M huggingface dataset:
データ系の用語についてまとめてみる

<h2>背景

データ分析に関心を持つ中で、多くの企業が分析の前のデータ分析基盤を構築することが出来ていない事を知る。
よくわかんない単語とサービスばっかりだったので、学びのアウトプットとして作成する。

データに関心あるけど、あんまりイメージわかないなって方の力になれたら嬉しい。

<h2>用語

大きな流れとしてはデータ分析基盤を構築→BIツールで可視化が多いみたい。
逆でもできるが、きれいな進め方としては上記。

下記に学んだ用語と意味を羅列していく。

<h3>データ分析基盤

そもそものデータを分析する前の、下記の役割を担う総称。

* データを取得する。
* データを保存しておく。
    * RDBとの違いは、テーブルデータのような構造化していないデータでなくてもいけちゃう。
        * 画像や音声ファイルなど
        * csvなどのテキストデータもいけちゃう。
* データの処理をする。
    * データをきれいにするよ。
* 処理したデータを保存しておく。
    * 汚いデータと混ぜちゃうと使いづらくなっちゃうからね。


<h3>データレイク

データ分析基盤の「データの保存をしておく」場所、サービスの総称。
生データやそれに近いデータが格納されている。

代表サービス：AWS S3、Google Cloud Strageなど

<h3>ETL

データをきれいにするよ！の作業やサービスの総称。

代表サービス：AWS Glue、Google Cloud Dataflowなど

<h3>データウェアハウス

きれいめなデータの保存場所。

代表サービス：Amazon Redshift、Google BigQuery、Snowflakeなど

<h3>BIツール

きれいなデータをグラフや図でわかりやすく見せる。

代表サービス：Tableau、Microsoft Power BI、Lookerなど

<h3>メタデータ

「このデータどんなデータ？」を教えてくれる情報の総称。

例：int型、カラム名など

<h3>Data Catalog（AWS Glue）

メタデータを伝えてくれるAWS Glueの機能の一つ。

<h3>Crawlers（AWS Glue）

データを取りに行ってくれるAWS Glueの機能の一つ。

<h3>Jobs（AWS Glue）

Data Catalogに沿ってデータを変換して、変換後のデータを保存してくれるAWS Glueの機能の一つ。


<h2>これから

まだまだわからないことがたくさん出そうなので、随時インプットしていく。
個人的には全くわかんなかったAWSのサービスが少しずつ分かってきて、楽しい。

一つずつ学んでいこうと思います。
ディスプレイのピクセル比取得

スマートフォンやタブレットでは デバイスピクセル比が2や3の機種がある。そのPixel数をWebで取得する方法のメモ。

```js
console.log(window.devicePixelRatio);
```
出力はそのデバイスのPixel比(1,2,3)がでる。
画面の座標を取得するときや`<canvas>`タグで描画するとき、ピクセル比が違うと、正しく動作しないことがあるので、どのデバイスでも正常に動作させるときに使用する。
```js
  if (window.devicePixelRatio === 1) {
    // デバイス比が1の時の処理
  } else if (window.devicePixelRatio === 2) {
    // デバイス比が2の時の処理
  } else if (window.devicePixelRatio === 3) {
    // デバイス比が3の時の処理
  }

```

#### 参考
https://www.javadrive.jp/javascript/webpage/index9.html
リーダブルコードで学んだこと

最近、Udemyでリーダブルコードに関する動画を視聴しました。
https://www.udemy.com/course/readable_code/

この動画では50のコードが読みやすくなる方法を紹介していて、その中から自分が特になるほどなって思った方法を2点紹介したいと思います。動画がC#で紹介していたのでここで紹介する例もC#で紹介します。

# メソッド内で変数を最初に宣言しない
　1個目は「メソッド内で変数を最初に宣言しない」です。これに関しては結構驚きでした。プログラム系の参考書を見ると、ソースコードの例で、最初に変数をまとめて宣言して書かれていることが多いからです。
　「悪い記法の例」で示したメソッドのような途中でreturnする場合は事前に宣言しておいた変数（filename2）は無駄になります。変数は使用する直前で宣言しましょう。

悪い記法の例
```c#
private void badMethod(){
    string filename1 = "file1";
    string filename2 = "file2";

    if(!System.IO.File.Exists(filenmae1)){
        //ここで抜けた場合、使用しない変数（filename2）の宣言は無駄になる
        return;
    }

    if(!System.IO.File.Exists(filenmae2)){
        return;
    }
    
}
```
良い記法の例
```c#
private void goodMethod(){
    string filename1 = "file1";
    if(!System.IO.File.Exists(filenmae1)){
        return;
    }

    // 変数は使用する直前で宣言する
    string filename2 = "file2";
    if(!System.IO.File.Exists(filenmae2)){
        return;
    }
    
}
```
# メソッド内のコメントではなくメソッド名で伝える
　2つ目は「メソッド内のコメントではなくメソッド名で伝える」です。自分が書いたソースが他の人にも伝わるようにするためについつい、メソッド内に多めにコメントを書いてしまいます。「悪い記法の例」のように処理のたびにコメントを書くのではなく、「良い記法の例」のようにメソッドの上にXMLコメントを書くとすっきりしたコードになります。また、「悪い記法の例」のメソッドの中のforeachの中身のようなパット見ただけじゃ分かりにくいコードはメソッド化して、そのメソッド名でどういう処理をしているのか伝えます。
　この方法を見ると、コメントでコードを細かく説明するよりもいかにして、少ない量で別のエンジニアにどういうコードかを伝えることが大事なのかなと思いました。

悪い記法の例
```c#
private void badMethod(){

    //filename1の中身が存在しないときreturnする
    string filename1 = "file1";
    var lines = System.IO.File.ReadAllLines(fileName);
    if(lines.Length < 1){
        return;
    }

    var products = new List<Product>();
    foreach(var line in lines){
        //値の上書きはしない
        int productId = Convert.ToInt32(line.Substring(0, 2));
        string productName = line.Substring(2, 10);
        int price = Convert.ToInt32(line.Substring(12, 2));
        //productsはここの直前で宣言しているので, 影響チェックが簡単
        products.Add(new Product(pproductId, productName, price, 0));
    }

    .
    .
    
}
```
良い記法の例
```c#
/**  
<summary>
ファイルを読んでプロダクトを生成する
</summary>
*/
private void generateProduct(){

    string filename1 = "file1";
    var lines = System.IO.File.ReadAllLines(fileName);
    if(lines.Length < 1){
        return;
    }

    var products = new List<Product>();
    foreach(var line in lines){
        products.Add(FileLineToProduct(line));
    }

    .
    .
    
}

/**  
<summary>
ファイルの1行をProductクラスに変換する
</summary>
*/
private Product FileToProduct(string line){
        int productId = Convert.ToInt32(line.Substring(0, 2));
        string productName = line.Substring(2, 10);
        int price = Convert.ToInt32(line.Substring(12, 2));
        return new Product(pproductId, productName, price, 0);
}

```

# さいごに
　今回の学びでリーダブルコード（読みやすいコード）についての理解が深まりました。この読みやすくなる書き方はもっといろいろな方法があると思うので続けて勉強していきたいと思います。
Azure Stack Development Kit を独自ドメインで使う。

# はじめに

Azure Stack Development Kit(ASDK)のドメインを変更する方法。
忘れないようにメモ。


:::note alert
警告
完全に非公式の手順になります。また今後のアップデートで適用できなくなるかもしれません。
自己責任でお願いします。
:::

# 現時点で できること/できないこと

### できること

AppService

ポータルサイトをインターネットからアクセスできるようになる。
手順は後で追加しますがCloudflareTunnelを使用します。

### できないこと

機能追加時に証明書を要求されるIaaS。

Azure Stack Hub上のSQL
証明書の問題がクリア出来きたらいけるはず...



# ソフトVer

Azure Stack Hub 2301 を使用。

# 準備

MS公式サイトのASDK のダウンロードと抽出を実施しCloudBuilderから起動していること。
https://learn.microsoft.com/ja-jp/azure-stack/asdk/asdk-download?view=azs-2301

:::note info
失敗したときのことを想定しCloudBuilder.vhdxはコピーを保管するのをおすすめします。
:::

# ドメイン書き換え
基本的に標準と構築手順が変わるのはこの箇所のみとなります。

※AppServiceなどIaaSを追加する際は別途対応が必要になります。

### スクリプト実行


CloudBuilder.vhdxから起動した後下記ps1をC:\CloudDeployment\Setupへ作成します。

https://gist.github.com/BjornAnd/b893e57c9913133b09ab533444425d51

その後下記のようにコマンドを実行。

```
cd "C:\CloudDeployment\Setup"
.\UpdateExternalFQDN.ps1 -ExternalDomainFqdn "適当なドメイン"
```


![スクリーンショット 2023-09-10 000235.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/973316/7285acb2-368b-a951-710c-7e8a040fae42.png)

![スクリーンショット 2023-09-10 000502.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/973316/31ac74ac-a14e-9ec7-c4c6-0f8f277890e5.png)

上記画面のように変更処理が入りその後は通常と同じようにインストールを実行してください。

### 確認
正常にインストールされると　https://adminportal.local."変更したドメイン"　
でアクセスできると思います。

![スクリーンショット 2023-09-10 000855.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/973316/acefb6ee-75f7-bab6-71e0-599549b4c158.png)

# AppServiceについて

前提条件にて必要な下記証明書についてはMSのヘルパースクリプトで取得可能ですが
Azure Resource Manager ルート証明書がエラーとなり取得できない状態になります。


・既定のドメイン証明書
・API 証明書
・公開証明書
・ID 証明書


https://learn.microsoft.com/ja-jp/azure-stack/operator/azure-stack-app-service-before-you-get-started?view=azs-2301&tabs=2022H1-connected%2C2022H1-disconnected&pivots=state-connected

その際は下記のように手動でエクスポートして使ってください。

証明書名　AzureStackSelfSignedRootCert.crt

![スクリーンショット 2023-09-10 002014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/973316/9428d916-01cf-dfe9-cea1-622b00f0906d.png)


# まとめ

以上でインストール手順は終了です。
あとはお好きにご使用ください。
DroidKaigi2023で内容の気になるもの３選

DroidKaigi2023が近くなり、タイムテーブルも公開してますね！
タイムテーブルを確認して、気になったものを３つ紹介しようと思います。


# よく見るあのUIをJetpack Composeで実装する方法〇選
Bumblebee － 2023/09/14 13:20-14:00

Jetpack Composeが最近どんどんと増えているのを感じているので、`よくあるUIの具体的な実装方法と注意点`というところに惹かれますね！
基礎的な知識があれば、Jetpack Composeの開発スピードも底上げできそうですね！

# Material 3 やめました
Dolphin － 2023/09/15 17:00-17:40

こちらもJetpack Composeです。
Material 3はアプリとして、カラーが統一していたりなど、UIのデザインとして、細かく調整ができない部分があったりします。なので、こちらの`独自のデザインシステムを Compose で構築`を知る事でエンジニアとしてレベルアップできると思います！


# MVIに基づくStateMachineアーキテクチャ：KMMとJetpack ComposeとSwiftUIを組み合わせる
Electric Eel － 2023/09/15 11:00-11:40

Jetpack ComposeとSwiftUIを勉強しているため、自分にとっては今一番知りたい内容です。
KMMも興味があるので、知りたい内容が沢山です！
今回のDroidKaigiで一番楽しみにています！

開催日が楽しみですね！
以上です！
Javaの関数型インターフェースとラムダ式

## はじめに

Javaの経験が浅いのに、RxJavaを使っている現場に配属され日々いろいろな壁にぶつかります。
今回は、自分が関数型インターフェース、ラムダ式についての理解が浅いために発生した疑問です。
※内容がRxJava寄りです。

### 今回の疑問点

**ラムダ式と関数型インターフェース**
関数型インターフェースの実装になぜラムダ式を代用することができるのか？
`.subscribe`メソッドのオーバーライドがどのように影響を受けるのか？

関数型インターフェースは、基本的には1つの抽象メソッドを持つインターフェースであり抽象メソッドを実装しないといけない。
だから、このような実装になることは理解出来ていました。
```java
 Flowable<String> flowable =
    Flowable.create(new FlowableOnSubscribe<String>() {
      @Override
      public void subscribe(FlowableEmitter<String> emitter) throws Exception {        
        String[] datas = { "Hello, World!", "こんにちは、世界！" };
        for (String data : datas) {
          if (emitter.isCancelled()) {
            return;
          }
          emitter.onNext(data);
        }
        emitter.onComplete();
      }
    },第二引数);
```
しかし、なぜラムダ式に変更すると、`.subscribe`オーバーライドは不要になるのかが理解できませんでした。

## 関数型インターフェースとは？

関数型インターフェースは、一つの抽象メソッドを持つインターフェースです。
```java
@FunctionalInterface
public interface FlowableOnSubscribe<T> {
    void subscribe(FlowableEmitter<T> emitter) throws Exception;
}
```

## ラムダ式とは？

ラムダ式は、関数型インターフェースの抽象メソッドの実装をコンパクトかつ簡潔な形式で提供する方法です。
これにより、匿名クラスの冗長な記法から解放され、コードの読みやすさと保守性が向上します。

## 例: FlowableOnSubscribeを使った実装

### 匿名クラス

```java
FlowableOnSubscribe<String> flowableOnSubscribe = new FlowableOnSubscribe<String>() {
    @Override
    public void subscribe(FlowableEmitter<String> emitter) throws Exception {
        String[] datas = { "Hello, World!", "こんにちは、世界！" };
        for (String data : datas) {
            if (emitter.isCancelled()) {
                return;
            }
            emitter.onNext(data);
        }
        emitter.onComplete();
    }
};
```

### ラムダ式

```java
FlowableOnSubscribe<String> flowableOnSubscribe = emitter -> {
    String[] datas = { "Hello, World!", "こんにちは、世界！" };
    for (String data : datas) {
        if (emitter.isCancelled()) {
            return;
        }
        emitter.onNext(data);
    }
    emitter.onComplete();
};
```

### Javaコンパイラはラムダ式を関数型インターフェースの唯一の抽象メソッドの実装として認識する。
NLBを使ってVPCピアリング環境下でEdge to Edgeを通信する

### はじめに
AWSではDirectConnectやVPCピアリングを使う環境下において、端から端（Edge to Edge）のネットワークへ通信ができない。そんな状況でもTCP通信できるようにしたい。シンプルなやりたいことに対して、あえてProxyサーバーを設けてメンテナンス工数を増やすもの違う気がするので、今回はELB（NLB）を使うことにした。

#### 現状
そのままではエッジツーエッジ接続ができない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54100/70fbc512-5bed-a87a-9a78-cfd3301f44da.png)

#### やりたいこと
NLBを使うと…通信できるはず
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54100/93d942b1-b702-2a17-b43e-8620e27fbae5.png)


### 今回作るもの
すでに存在するVPC`NLBVPCid`、サブネット`NLBsubnetID`内にNLBを作成する。作成するものは3つ。CloudFormationで用意する。使わないときはスタックごと立ち下げる。

- NLB本体
- NLBのターゲットグループ：ルーティング対象
- リスナー：NLB本体とターゲットグループの接続を定義
 
### CloudFormationテンプレート


今回ターゲットグループの対象には2つのIPアドレス(`Target01IpAddress0*`)を指定するようにした。**注意点は、ターゲットグループを作成する際、対象となるIPアドレスが存在しないとエラーが発生してスタック作成が失敗するところ。** ターゲットグループの対象とするリソースを用意してからスタックを作る必要がある。作ったものはGitHubに置いた。


https://github.com/bd8z/nlbVpc.git



```yaml:template.yaml
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
  UUID:
    Description: UUID of stack items
    Type: String
  NLBVPCid:
    Description: VPC whare to place NLB
    Type: String
    Default: vpc-xxxxxxxxxxxxxxxxx

  NLBsubnetID:
    Description: subnetID
    Type: AWS::EC2::Subnet::Id
    Default: subnet-xxxxxxxxxxxxxxxxx

  #you add more ipaddr&port as much as you want
  PortToSend01:
    Description: TCP Port to send
    Type: Number
    Default: "3389"
  Target01IpAddress01:
    Description: NLB target ip address
    Type: String
    Default: "10.0.2.xxx"
  Target01IpAddress02:
    Description: NLB target ip address
    Type: String
    Default: "10.0.2.xxx"

Resources:
  NLB:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties: 
      IpAddressType: ipv4
      Name: !Sub "myNLB-${UUID}"
      Scheme: internal
      Subnets:
        - !Ref NLBsubnetID
      Type: network
  NLBTargetGroup01:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties: 
      HealthCheckEnabled: true
      IpAddressType: ipv4
      Name: !Sub "myNLBTargetGroup01-${UUID}"
      Port: !Ref PortToSend01
      Protocol: TCP
      Targets: 
        - Id: !Ref Target01IpAddress01
          Port: !Ref PortToSend01
        - Id: !Ref Target01IpAddress02
          Port: !Ref PortToSend01
      TargetType: ip
      VpcId: !Ref NLBVPCid
  NLBListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties: 
      DefaultActions: 
        - Type: forward
          TargetGroupArn: !Ref NLBTargetGroup01
      LoadBalancerArn: !Ref NLB
      Port: !Ref PortToSend01
      Protocol: TCP
```


### 終わりに
今回の使い方において良いところは拡張性だと思う。NLBは高可用性がAWS側で担保されている（≒単一障害点にならない）ので、今後VPCがどれだけ増えても、構成そのままにNLBをそのまま使うことができる。

痒い所もある。ELBでは、ターゲットグループのターゲットとしてIPアドレスorインスタンスIDを指定する。ドメイン名が用意されていても、指定ができない。（プライベートネットワークでもドメイン名を指定したいような場合、結構あると思うのだけど。）IPアドレスがころころ変わってしまうような環境の場合は、Lambdaを使って、スタックの更新を自動で行うようにするしかないかな...。
ECDSAについて調べてみた

# はじめに
ECDSAについて、自分が調べたり理解したことをまとめていきます。

まとめようと思ったきっかけは以下の通りです。
・暗号分野は完全に初心者で「ECDSA」で調べても書いている内容が分からない
・ECDSAの解説サイトを見ると、みなさん同じような内容で解説してらっしゃるのですが、もう一段落とした内容じゃないと理解できない（解説してる方々の前提知識が高すぎる！）
・普段ECDSAを使ったり意識したりしないので、ある程度落とした内容をまとめておかないと忘れる

# ECDSAとは
Elliptic Curve Digital Signature Algorithmの略です。
Elliptic Curve ＝ 楕円曲線
Digital Signature Algorithm＝ デジタル署名アルゴリズム

つまり、楕円曲線を使ってデジタル署名を行うものらしいです。
ちな、暗号としてRSAって用語もあります。
RSAは共同で発明した人が3人いて頭文字を取っただけなので、末尾にSAって付いてるんですが何も関係ないみたいです。

じゃ楕円曲線ってどんなんや？ってなると、以下の式であらわされる楕円曲線のようです。
```math
y^2 = x^3 + ax + b
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554089/25aea926-342b-3cdb-6f88-938a63180f28.png)
調べる途中でたぶん30回は見たこの形のグラフ

まとめると、ECDSAはこの曲線を使って、データを暗号化しデジタル署名を行うものです。


# どうやってデジタル署名するの？
例として今回はビットコインの公開鍵暗号方式でトランザクションを署名する際にECDSAの使われ方を想定します。
(今の私の知識では、ECDSAが他にどういう使われ方するのか等は知りません！)

まずは公開鍵暗号なので、公開鍵と秘密鍵が必要です。
公開鍵と秘密鍵の式は以下の通りです。
```math
K(公開鍵) = k(秘密鍵) × G(楕円曲線上の座標)　・・・①
```
kはランダムな数字です。
Gは公開鍵生成のための座標、Generating point でGです。

トランザクションにデジタル署名をして署名データを作る流れは以下の通りです。
署名データを作る際に、一時的な公開鍵を作ります。
一時的な公開鍵R = 一時的な秘密鍵q × G　・・・②
そして、一時的な公開鍵Rのx座標を署名に使います。
```math
署名データ =  \frac{Txデータのハッシュ +秘密鍵k × 一時的な公開鍵Rのx座標}{一時的な秘密鍵q}　・・・③
```
そして、この**署名データ**と**一時的な公開鍵Rのx座標**をトランザクションとして送ります。


# どうやって署名を検証するの？

署名データの受信者は、デジタル署名が正しいか検証します。

受信者は、署名データと公開鍵Kのx座標を受け取った後、以下の計算をして検証Qを求めます。

```math
検証Q = \frac{Txデータのハッシュ}{署名データ}G + \frac{一時的な公開鍵Rのx座標}{署名データ}送信者の公開鍵K
```
検証Qを計算した上で何をもって検証OKとするかというと、検証Qと受信した**一時的な公開鍵Rのx座標**が一致したらOKと判断します。

検証を計算していくと、
```math
検証Q = \frac{(TXデータのハッシュ)G + 一時的な公開鍵Rのx座標 × 送信者の公開鍵K}{署名データ}
```
↑単純に分数の足し算しただけです。

となって、送信者の公開鍵Kっていうのは①の通り、K=秘密鍵k × Gなので、
```math
検証 = \frac{(TXデータのハッシュ)G + (一時的な公開鍵Rのx座標)(送信者の秘密鍵 × G)}{署名データ}
```
となります。
そこから、Gを抜き出すと、
```math
\frac{TXデータのハッシュ + (一時的な公開鍵Kのx座標)(送信者の秘密鍵)}{署名データ}G ・・・④
```
となり、④の「署名データ」に、③を代入して、「Txデータのハッシュ + 一時的な公開鍵Rのx座標 × 送信者の秘密鍵k」で約分すると残るのは、
```math
一時的な秘密鍵q × G
```
となります。
これは、送られてきたデータ**一時的な公開鍵Rのx座標**と同じ意味ですね。(②を見てね！)
なので、送信者がちゃんと秘密鍵で署名したデータで、中身も改ざんされていないことが検証できました。

トランザクションのハッシュと送信者の公開鍵を、署名データで約分できたからOK！と考えるとイメージしやすいのではないでしょうか。


# 最後に
なんかECDSAのまとめじゃなく、デジタル署名と検証の仕組みになった感が否めなくなりました。
今回、あくまでECDSAの署名ということで、公開鍵と秘密鍵を作るGについての説明は書きませんでしたが時間があったらまとめようかと思います。

間違っている箇所があったら指摘してもらえると、私が物凄い喜びます。勉強になるので。
なーんかまだ検証の章の最後が甘い気がするんですよね…


参考にさせていただいたURL
https://www.youtube.com/watch?v=RC_UupaAjSc
https://www.etarou.work/posts/4968764/
↑エグい分かりやすかったです。是非見て・読んでください。
その他ECDSAで検索すると出てくる記事・ブログの方々
HTTPヘッダから誰が応答しているかを確認する。

# 概要

Webページのアクセス先の内容を確認するために、ヘッダを確認したいという事がある。
その時は、curlコマンドで確認してみよう。


# 実行コマンド
```
curl -I urlまたはfqdn
```
```:実行結果
HTTP/1.1 404 Not Found
Date: Sat, 09 Sep 2023 14:37:06 GMT
Server: WSGIServer/0.2 CPython/3.11.0
Content-Type: text/html; charset=utf-8
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
Cross-Origin-Opener-Policy: same-origin
Set-Cookie: xascszzzzzzzzzzzzzzz
```
そして、ここでいう`Server`の欄が、返答している者である。

サーバによっては、nginxだったりが返答している事もある。
```
[user@server~]$ curl -Ik https://略
HTTP/1.1 200 OK
Server: nginx/1.22.1
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/8.1.2
Cache-Control: no-cache, private
略
```

リダイレクトになっているかは、`Location`で確認できる。
以下のように、Locationがhttpsでそのままつけられて表示されているときは、
- httpsをつけて実行
- もしくは`curl -L`
でリダイレクト先を確認できる。
```:リダイレクト先が表示されえない
[user@server~]$ curl -Ik https://sample~~
HTTP/1.0 302 Moved Temporarity
Location: https://sample~~
Server: BIGIP
Connection: keep-alive
Content-Length: 0
```

```
curl -I https://~~~
もしくは
curl -IL htttp://~~
```

実行結果
```
[user@server~]$ curl -Ik https://略
HTTP/1.1 200 OK
Server: nginx/1.22.1
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/8.1.2
Cache-Control: no-cache, private
略
Stringって何なんだ？

先日業務で拡張for文を扱う場面があり、少々はまったのでメモ。

まず、拡張for文とは何かをまとめておく。
```
Hoge hoge1 = new Hoge();
Hoge hoge2 = new Hoge();
Hoge hoge3 = new Hoge();

List<Hoge> hogeList = new ArrayList<>();
hogeList.add(Hoge1);
hogeList.add(Hoge2);
hogeList.add(Hoge3);

// ここから拡張for文
for(Hoge hoge : hogeList){
    hoge.~~なにかしらの処理
}
```

とまあこんな感じにコードを記載する。
すると、HogeListの要素が一つづつhogeに取り出されて、すべての要素に対して繰り返し処理を行うことができる。

## hogeに代入されるもの
ここで気になったのが、hogeには参照が渡されるという点。
hogeに参照が渡される以上、拡張for文の中でhogeに対して何かしらの処理を施した場合、
hogeListの要素が指している参照先が更新されることになる。要はhogeListの中身が更新される。
ここまでは参照型の仕組みについて把握していれば理解はできた。


## 参照型でもStringの場合は話が違うらしい。
問題はStringを扱った場合。ここでString型に対する知識不足が露呈。理解が追い付かなくなった。

まずは事象の整理から。
```
String A = "AAA";
String B = "BBB";
String C = "CCC";

List<String> stringList = new ArrayList<>();
stringList.add(A);
stringList.add(B);
stringList.add(C);

for(String str : stringList){
    str = "Foo";
}

for(String str : stringList){
    System.out.println(str);
}

結果
+++++++++++++++++++++++++++++++++++++++++
AAA
BBB
CCC
+++++++++++++++++++++++++++++++++++++++++
```
for文でListの中身をすべて"Foo"に上書きしたのに、なぜか初期化した状態から変わっていない。

なぜ？と思いながらあれこれ考えているうちに、曖昧ながらなんとなく思い出してきた。
「Stringは不変」みたいな性質あったなぁと。

そもそもStringの不変性についてそこまでしっかり理解しているわけではなかったので、もしかしてこれが関係しているのか？と気が付いたはいいものの結局どういう理屈なのかは未だに理解できていない。
デバッグしてみて、Stringの場合は参照渡しではなく値渡しになるんだなというところで一旦着地した。

## 結局根本的なところはまだ理解できていない
今回は拡張for文をきっかけに、自分がStringに対してすごく無知であることに気づかされた。

「Stringの不変性」このキーワードで少し勉強します。
FlutterでFirebaseのアカウントを切り替える

FirebaseはGoogleアカウントに紐づいている。
現在使っているFirebaseのGoogleアカウントを変更したい（Firebase CLIのログインアカウントを切り替えたい）というときに、行うべき操作。

# 1. Firebase CLIのアカウントを切り替え
```console
firebase logout
firebase login
```
切り替えたいアカウントを選択。

# 2. Firebase CLIにプロジェクトを追加する
```console
firebase use --add
```
loginしているアカウントに紐づいているプロジェクトが一覧で表示されるので、Flutterで使いたいプロジェクトを選択。

# 3. flutterにプロジェクトを紐付ける
```console
flutterfire configure --project=<YourProjectName>
```
色々と上書きの確認をされるが、すべてyes。

# 4. Firebaseを初期化
```console
firebase init
```
必要なFirebaseの機能を初期化する。基本的にはFirestore。エミュレータを使う場合、Emulatorも初期化。


以上。
NiZ製のキーボードでキーマッピングに行き詰まったときに見る記事

hhkbから静電容量無接点方式のキーボードにはまり、NiZを購入したものの、キーマッピングをいじっていたら突然キー入力が一切効かなくなってしまったような読者にむけてこの記事をおくります。

＜検証環境＞
・windows 11
・NiZ 82EC(S)Ble

＜直し方＞
１， キーボードを初期化する
キーボード四隅のキーを同時に、8秒間押し続ける。
すると、ScrLkのライトが点灯するので指を離す。

https://support.akeeyo.co.jp/hc/ja/articles/4412793262617-%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89-%E3%83%AA%E3%82%BB%E3%83%83%E3%83%88%E6%96%B9%E6%B3%95%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6


＜キーマッピングの仕方＞
１，AKEEYOのサイトから、キーマッピング用のファイルをダウンロードする
NiZ公式からもダウンロードはできるが、何故か最新版のデータが見つからない。
最新版のバージョンがほしいのならばAKEEYOからデータにアクセスするのが得策。
AKEEYOからアクセスした先にデータが複数あるが、4つとも全部ダウンロードしてください。

https://www.akeeyo.co.jp/pages/support

２，ダウンロードした .exe　ファイルを「すべて展開」する
「実行」ではありません

３，PCにNiZのキーボードを接続する


４，展開してできたファイルの中の、 .exe　ファイルを開く

５，好きなようにキーマッピングする

６，「WriteKeys」を押す

７，「Save」を押す

８，NiZキーボードの「fnキー・側面にⓂ（今回の環境では、右上のDelキー）」と書かれたキーをライトが点滅するまで押す

＜補足＞
・７をする理由
ネット上や説明書に書かれている方法では、キーマップソフト上の「ReadAll」を押せばキーボードに保存されているキーマップがソフト上に反映されると書かれているものの、ソフトが落ちてしまうため、２回目以降に初期状態からキーマップをするはめになってしまうから。

・８をする理由
NiZのキーボードには、標準の「Officeモード」と、カスタマイズ性のある「Programモード」があるらしい。キーマップが初期の状態{Officeモード)から、キーマップを変更していないのにProgramモードに変えてしまうと、検証環境では一切のキー入力をうけつけなくなった。
キーマップを変更した状態から、programモードに変更すると、ソフト上で変更したキーマップが反映されるようになる。
なお、２回目以降にキーマップを変更する際には、モード変更を行う必要はない。「Open」で直前に保存したキーマップを開いてから、手順５，６，７ を繰り返してください。
フロントエンド開発の変遷① JavaScriptの黎明期とjQuey

もっと技術の歴史や生まれた背景を知るべく、今回はフロントエンド開発の変遷について学びました。今回は第1回「JacaScriptの黎明期とjQueryです」
書籍「TypeScriptとReact/Next.jsで作る実践Webアプリケーション開発」を参考にしています。

https://www.amazon.co.jp/TypeScript%E3%81%A8React-Next-js%E3%81%A7%E3%81%A4%E3%81%8F%E3%82%8B%E5%AE%9F%E8%B7%B5Web%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E9%96%8B%E7%99%BA-%E6%89%8B%E5%B3%B6-%E6%8B%93%E4%B9%9F/dp/4297129167

### JavaScriptの黎明期とjQueryの人気
JavaScriptは1995年に誕生します。JavaScriptはNetscape社が開発したブラウザ上で動くスクリプト言語として登場。同時期にMicrosoftもWindowsにInternet Exploerを搭載し、JavaScriptに似ている言語JScriptが動作するブラウザを実装しましたが、JavaScriptと非互換な部分も多く、ブラウザ間で挙動が異なる開発者の頭を悩ませていた。

そのような背景でECMAという標準化団体によるJavaScriptの標準化策定が始まります。しかし、Mozilla（旧NetScape）、Microsoft、Adobe、Yahoo！など当時Webをリードする大企業の意見が分かれなかなか標準化が進みませんでした。

その後、2005年にGoogleが地図サービスGoogleMapsをリリースして、JavaScriptが注目を浴びます。Google Mapsは非同期でHTTP通信をするAjaxを活用し、Webでインタラクティブなアプリケーションを実現。AjaxはAsynchronous JavaScript and XMLの略で、JavaScriptを用いて非同期にデータ通信をする実装方法を指します。ページをリロードすることなく必要な部分だけサーバーから情報を取得しUIを更新するこの技術は今では当たり前ですが、当時Webサイトのお化粧程度でしか使われなかったJavaScriptが再注目されます。

このAjaxを活用したWebアプリケーションの開発は世界中に広まり、以下のような多くの開発でJavaScriptが活用されるようになりました。
* Gmailのようなメールアプリケーション
* リアルタイム性の高い分析ツール
* SNSの実装
* ゲームの開発

さらにJavaScriptを多用したWebアプリケーションを普及させたきっかけとして、2008年Google Chromeの誕生が挙げられます。ChromeにはV8というJIT VM型のJavaScriptエンジンが搭載され、JavaScriptの実行速度が飛躍的に上がりました。

結果的にWebアプリは、ブラウザ上で動くアプリとして当時健在だったJavaアプレットやFlashなどで作るアプリケーションと比べてもパフォーマンスが劣らなくなってきました。ブラウザさえあれば、インストール不要で実行できるJavaScriptを活用したWebアプリケーションはますます普及してきました。

上記のように、JavaScriptはもともと必ずしも良いイメージを持たれていたわけではありません。ブラウザの進化とともに多くの画期的なWebアプリケーションが生まれ、次第に人々の認識が変わり、世界中で多くのエンジニアに利用される、人気の高い言語へと生まれ変わりました。

第2回へ続く、、

https://qiita.com/yusuke2310/items/2c58a1fb08b1bb5b3350
AWS EventBridge Scheduler の execution role の trust policy に SourceArn の条件をつけてはいけない

事の発端は AWS から "[NOTIFICATION] Changes to EventBridge Scheduler IAM Roles" というタイトルのメールが届いたこと。英文でごちゃごちゃ書いてあったものの、要は

> EventBridge Scheduler の execution role で指定している trust policy に
> schedule 自体の arn が aws:SourceArn 条件として指定されているが、
> 2023年9月7日以降、trust policy の aws:SourceArn 条件としてサポートされるのは
> schedule-group の arn だけです(既存のものは動くけどね)

ということらしい。

[AWS のドキュメント](https://docs.aws.amazon.com/scheduler/latest/UserGuide/cross-service-confused-deputy-prevention.html) でも、確かにそういう例が書いてある。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "scheduler.amazonaws.com"
            },
            "Action": "sts:AssumeRole",
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": "123456789012",
                    "aws:SourceArn": "arn:aws:scheduler:us-west-2:123456789012:schedule-group/your-schedule-group"
                }
            }
        }
    ]
}
```

ならばと、やってみた。IAM role の trust policy を編集して、schedule 自体の arn を指定しているところを、その schedule が属している schedule-group の arn に変える。

…
…
…

動かなくなったじゃないか。

試しにと、AWS 管理コンソールでイチから schedule を作って、どんな IAM role が生成されるのか検証してみた。 trust policy のところだけ抜粋。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "scheduler.amazonaws.com"
            },
            "Action": "sts:AssumeRole",
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": "123456789012"
                }
            }
        }
    ]
}
```

aws:SourceArn の条件、なくなってるじゃん！確かに、この設定なら動いた。

教訓：ドキュメントやメールの文章を鵜吞みにしてはならない。AWS のふるまいは検証してみないとわからない(ことがある)。

まぁそのうち、ドキュメントに書いてあるとおりの動きに修正されるのかもしれませんけどね。
ルーティング（ネットワーク層）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/9ff9380b-e7a0-d11c-ba01-ca599449580c.png)
　IPでは、ヘッダ中の宛先IPアドレスをどこに配送すれば良いのかを決めます。IPによる配送の基本的な考え方は、「宛先が自分の知り合いであれば直接渡す」「知り合いでなければ隣人の人に渡す」です。隣の人に渡した結果は、パケットが最終的に宛先まで届くのかがわかりません。非常に無責任な配送方法です。こういった理由で、IPによる通信は「信頼性のない言語」と呼ばれます。つまり、相手に正しく届くかどうかは保証されない通信であるということです。しかし、このいい加減さが、ネットワークの一部が停止しても、他の大部分は通常通り動くというインターネットの最大の利点につながっています。

１：ルータ
　ルータは、宛先IPアドレスを見て、適切な経路にパケットを中継する装置です。宛先IPアドレスを見て、中継先を決めることを「ネットワーク層レベルでの中継を行う」と言います。ルータには、複数のNIC（ネットワークカード）が取り付けられています。

２：ルーティングの仕組み
　ルータは経路制御表（ルーティングテーブル）を持っており、経路制御表で指示された通りにパケットの中継を行います。ルーティングの基本的な考え方は、
①ルータ自身が直接接続されているネットワーク宛のパケットは、直接配送する。

②それ以外のパケットは、隣のルータ（デフォルトルータとか、ネクストホップルータ）に渡す。

３：ルーティング方式とルーティングプロトコル
　経路制御表を手動で設定する方式をスタティックルーティングと言います。ネットワークの規模が小さい時には便利でうs。

　一方で、ネットワークの規模が大きくなると、手動での設定は困難になります。そこで、ルータ同士で経路情報の交換を行い、自動的に経路制御表を設定する方式を用います。自動で経路制御表を設定する方式をダイナミックルーティングと言います。

　ダイナミックルーティングを行うためのプロトコルには２つあります。

①RIP：経由するルータの台数（ホップ数という）が最も少なくなる経路に中継する方式である。このような、アルゴリズムをディスタンスペクタ型（距離ベクタ型）という。

②OSPF：ホップ数以外にも、ネットワークの混雑度、回線速度などの様々な要素を考慮して、トータルバランスの良い経路に中継する方式である。このようなアルゴリズムをリンクステート型という。

４：IPパケットとイーサネットフレーム
　アプリケーションプログラムは、宛先IPアドレスを指定して、相手に送りたいデータをOSに渡します。OSは、これらの情報をもとにIPパケットを生成します。生成されたIPパケットは、イーサネットを使ってルータに届けられます。イーサネット上では、イーサネットフレーム形式にしなくてはなりません。そこで、IPパケットをイーサネットフレームに箱詰めして、イーサネット上を伝えます。IPパケットをそのままイーサネットフレームに箱詰めすることをカプセル化と言います。

５：LAN間接続装置の分類
　ネットワークを相互にそつ属する装置は、機能によって、下記のように分類できます。

①ゲートウェイ：特徴は全階層のプロトコル変換機能を持つ。

②ルータ　L3スイッチ：ネットワーク層での中継を行う。IPアドレスに基づいて経路の選択/中継を行う。

③ブリッジ　L2スイッチ　スイチングハブ：データリンク層での中継を行う。MACアドレスに基づいてフレームを中継する。

④リピータ：物理層での動作を行う。電気信号を増幅する。

６：SDN(Software-Defined Networking)
　物理的なネットワーク機器の接続にとらわれず、柔軟にネットワークを構成できるようにする仕組みです。SDNの代表的な技術にOpenFlowでは、データ転送に特化したネットワーク機器（スイッチ）を、コントローラと呼ばれるソフトウェアで制御管理することによって、物理的な配置や配線を変更することなく、ネットワークを柔軟に構成することができます。
[備忘録] homebrewでインストールしたpostgreSQLの起動が失敗する

homebrewでインストールしたpostgreSQLの起動が失敗したので備忘録。

## postgreSQLを起動する

postgreSQLはHomebrewでインストール済み。

```zsh
$ brew services run postgresql@14
==> Successfully started `postgresql@14` (label: homebrew.mxcl.postgresql@14)
```

`brew services run`で起動すると、無事に起動したように見えるが
`psql`を実行しようとするとエラーになる。

```zsh
$ psql -d postgres

psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such file or directory
	Is the server running locally and accepting connections on that socket?
```

## `brew services`を確認するとコケている

```zsh
$ brew services
Name          Status     User File
postgresql@14 error  256 nako ~/Library/LaunchAgents/homebrew.mxcl.postgresql@14.plist
```

## ログを確認する

`/opt/homebrew/var/log/postgresql@14.log` にログを吐いているようなので、そちらを見てみる。

```
$ view /opt/homebrew/var/log/postgresql@14.log
〜 略 〜
2023-09-09 21:31:23.054 JST [84735] FATAL:  could not create shared memory segment: Cannot allocate memory
2023-09-09 21:31:23.054 JST [84735] DETAIL:  Failed system call was shmget(key=5133258, size=56, 03600).
2023-09-09 21:31:23.054 JST [84735] HINT:  This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMALL parameter.  You might need to reconfigure the kernel with larger SHMALL.
        The PostgreSQL documentation contains more information about shared memory configuration.
```

割り当てられているshared memoryが足りないらしい。

## 共有メモリの値を変更する

`/etc/sysctl.conf`ファイルを作成し、設定を記述する。

```zsh
$ sudo vim /etc/sysctl.conf

kern.sysv.shmmax=536870912
kern.sysv.shmmin=1
kern.sysv.shmmni=4096
kern.sysv.shmseg=1024
kern.sysv.shmall=131072
```

## Macを再起動する

カーネルパラメータを変更したので再起動する。

## 参考にした記事

https://tech.kurojica.com/archives/7949/

http://sweng.web.fc2.com/ja/software/macosx/mac-os-shmmax.html
【SwiftUI】アプリのメニューを編集する

# はじめに
Macアプリだとメニューが編集できます。
そのやり方を記事にします

# こんな感じにカスタマイズできる
![スクリーンショット 2023-09-09 22.03.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/b48b8022-350e-c985-9742-ca52b4f93672.png)

# 実装
```swift
import SwiftUI

@main
struct sample_macOSApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .commands {
            CommandMenu("sample1") {
                Button {
                    print("sample1 action")
                } label: {
                    Text("sample1 action")
                }
            }
            
            CommandMenu("sample2") {
                Button {
                    print("sample2 action")
                } label: {
                    Text("sample2 action")
                }
            }
            
            CommandMenu("sample3") {
                Button {
                    print("sample3 action")
                } label: {
                    Text("sample3 action")
                }
            }
        }
    }
}
```

# おわり
`CommandMenu`は知りませんでした、、、
Windows Search で特定のドライブを検索対象にできない

# 前提
- OS: Windows 11
- PC に接続されたドライブ: C, D（ここまで SSD）; E, F, G（ここまで HDD）
- 元々 Windows 10 を使っていたが，最近 Windows 11 に OS を入れ替えた．C ドライブ以外は Windows 10 時代のものをそのまま流用

# 症状
タスクバーの「検索」(Windows Search) から特定のドライブ（具体的には D・E・G）がで検索できない．

通常，Windows Search の検索対象フォルダを指定するには，以下の手順で検索場所を指定してやればよい．
1. [Win]+[I] で「設定」ウィンドウを出す
1. 左上のハンバーガーボタン（三）から「プライバシーとセキュリティ」を開く
1. 「Windows 検索」をクリック
1. 「ファイルを検索」内にある「検索場所をカスタマイズする」をクリック
1. 「インデックスのオプション」ウィンドウが開くので「変更」をクリック
1. 「インデックスが作成された場所」ウィンドウが開くので，「選択された場所の変更」から検索対象にしたいフォルダにチェックを入れて「OK」をクリック

しかし，この「選択された場所の変更」にそもそも D・E・G ドライブが表示されない．

# 原因

D・E・G ドライブ直下の "System Volume Information" のアクセス権限が不適切だった．

※正確には以下の解決手法を実施すると直ったので，きっとこうだろうという推測．公式ドキュメント等で仕様を確認したわけではない．

# 解決手法

1. 表示されなかったドライブ直下の "System Volume Information" を右クリックして「プロパティ」をクリック
1. 「セキュリティ」タブを開き，下の方の「詳細設定」をクリック
1. 以下の手順で所有者を Administrator に変更
    1. 「所有者」欄の「変更」をクリック
    1. 別に表示されるウィンドウの「選択するオブジェクト名を入力してください」に「Administrator」を入力して「OK」をクリック
    1. 「サブコンテナーとオブジェクトの所有者を置き換える」にチェックを入れる
1. 以下の手順で SYSTEM にアクセス権限を与える
    1. 「アクセス許可」の「追加」をクリック
    1. 「プリンシパルの選択」をクリックすると別ウィンドウが表示されるので，「選択するオブジェクト名を入力してください」に「SYSTEM」を入力して「OK」をクリック
    1. 「基本のアクセス許可」の「フル コントロール」にチェックを入れて「OK」をクリック
    1. 「子オブジェクトのアクセス許可エントリすべてを、このオブジェクトからの継承可能なアクセス許可エントリで置き換える」にチェックを入れる
1. 「OK」をクリック
1. [Win]+[R] で「ファイル名を指定して実行」を開き，名前に「services.msc」を入力して「OK」をクリック
1. 「Windows Search」をクリックし，左上の「サービスの再起動」をクリック

なお，これは検索対象に表示されていたドライブと同じアクセス権限を，表示されていないドライブにも頭を空っぽにしてコピーしただけなので，これらのうち，どれが本当に必要だったのかは不明．

# 補足

「前提」に書いた通り，今回 検索対象に表示されていなかったドライブは Windows 10 の PC から流用したものだが，そのときドライブ内のファイル・フォルダの権限を書き換える作業をした．このとき何も考えずに "System Volume Information" の権限も一緒に書き換えたために起きたと思われる．

# 蛇足

この問題を解決するために色々ググったものの，なかなか解決できず，貴重な休日を半日も潰してしまいました．なのでせめて同じ問題に悩む人が時間を無駄にしないようにドキュメント化して公開しておきます．
Pokémon Sleepのサードパーティライセンスを見てみた

Android/iPhoneアプリの開発をする上で参考にできればと思って眺めていたところ、結構な数のライブラリが使用されているようでどんなものが使われているのか調べてみたメモ。

# .NET/C#関連のライブラリ

## SQLCipher

SQLiteの中身を暗号化するライブラリ。セーブデータの暗号化とかに使っている？

https://www.zetetic.net/sqlcipher/

## ZXing.NET

C#で2次元コードを読み込んだりするときによく使われているライブラリ。
フレンド登録の2次元コードの生成・読み取りに使用されている？

https://zxing.net/

## Utf8Json

C#向けのJSONシリアライザー。高速動作が特徴なのでゲーム開発との相性がよい？

https://github.com/neuecc/Utf8Json

# Unityに使うライブラリ

## unity-webview

GREE社が作成しているUnityでWebViewを実装するためのライブラリ。
ゲームアプリではよくお知らせやニュースの表示などに使用される。

https://github.com/gree/unity-webview

## NaughtyAttributes

UnityのPropertyAttributeを拡張するプラグイン。
様々な入力コンポーネントのプロパティをUnity上で編集できるようになる。

https://github.com/dbrizov/NaughtyAttributes

## apple-signing-unity

AppleアカウントでサインインできるようにするためのSDK。

https://docs.unity.com/ugs/manual/authentication/manual/platform-signin-apple

## UnityMobileInput

iOSとAndroidのネイティブ入力文字をそのまま文字化けなしで描画できるInputField。

https://github.com/mopsicus/UnityMobileInput

## unity.webp

WebP形式の画像をUnityで使うためのライブラリ。

https://github.com/netpyoung/unity.webp

## DOTween

Unity上でゲームオブジェクトのアニメーションを作成・編集できるプラグイン。

https://assetstore.unity.com/packages/tools/visual-scripting/dotween-pro-32416

https://assetstore.unity.com/packages/tools/animation/dotween-hotween-v2-27676

## UniRx

UnityでReactive Programmingを実現するためのライブラリ。

https://github.com/neuecc/UniRx

## UniTask

Unityで非同期処理を高パフォーマンスに使用できるようになるライブラリ。

https://github.com/Cysharp/UniTask

## ParticleEffectForUGUI

uGUIでオーバーレイやマスク処理をしながらパーティクルエフェクトの描画ができるライブラリ。

https://github.com/mob-sakai/ParticleEffectForUGUI

## SoftMaskForUGUI, UnmaskForUGUI

uGUIで綺麗にマスク処理を描画できるライブラリ。

https://github.com/mob-sakai/SoftMaskForUGUI

https://github.com/mob-sakai/UnmaskForUGUI

## spine-runtimes

2Dに特化したアニメーションツールSpineのUnity向けランタイム。

https://github.com/EsotericSoftware/spine-runtimes

## Adjust Unity SDK

アプリ内のユーザー利用状況などを収集・分析するツールAdjustのUnity向けSDK。

https://github.com/adjust/unity_sdk

## firebase-unity-sdk

Googleの提供するモバイル開発プラットホームであるFirebaseのUnity向けSDK。

https://github.com/firebase/firebase-unity-sdk

## jQuery

WebViewで表示する何かに使用されている？

https://jquery.com/

# フォント

## M+ 1p Heavy

視認しやすくよく利用されているフォント。

https://mplus-fonts.osdn.jp/

## Source-han-sans

Adobe Fontsにも入っているフォント。日本語は源ノ角ゴシック。

https://github.com/adobe-fonts/source-han-sans

## Montserrat

Google Fontsにも入っている英文フォント。

https://fonts.google.com/specimen/Montserrat

# Go PLUS +関連？

おそらく[Pokémon GO Plus +](https://www.pokemongoplusplus.com/)との連携に使用しているのではないかと思われるライセンスも含まれていた。

## ARM

言わずもがなのプロセッサー。

https://www.arm.com/

## mbedtls

組み込みC向けのSSL/TLSライブラリ。

https://github.com/Mbed-TLS/mbedtls

## nRF5

Nordic Semiconductor社のnRF5xシリーズ(SoC)向けSDK。
ARMプロセッサとBluetoothのプロトコルを内蔵するSoCらしい。

https://www.nordicsemi.com/Products/Development-software/nrf5-sdk

## SoftDevice

nRF5x向けのプロトコルスタック。

https://www.nordicsemi.com/Products/Bluetooth-Low-Energy/nRF5-SDK-and-SoftDevice
【Keras】【TensorFlow】教師あり学習fitの「batch_size」の技術検証

# 検証を行うきっかけと目的

　同じデータや内容のAIの作成を行う場合でも⓵どの端末で行ったか⓶学習の変数の一つである「batch_size」が違うだけで大きく結果が異なるように見えたため。端末ごと、batch_sizeごとにどのような影響があるか検証する。

　上記の⓵と⓶以外は前回の下の記事をそのまま流用している。
AIチャレンジ１（天気予報）
https://qiita.com/horiivalue/items/639e2e9c8b83c8d4886a

# fitの変数「batch_size」とは？

　そもそも、この「batch_size」は何を算定しているのか？
以下のQ&Aなどを参照してまとめてみると以下のようになる。
⓵kerasのbatch_sizeについて（分からない）
https://teratail.com/questions/191679
⓶Kerasのドキュメント
https://keras.io/ja/models/model/#:~:text=batch_size%3A%20%E6%95%B4%E6%95%B0%E3%81%BE%E3%81%9F%E3%81%AF%20None,%EF%BC%8E%E5%8B%BE%E9%85%8D%E6%9B%B4%E6%96%B0%E6%AF%8E%E3%81%AE%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E6%95%B0%E3%82%92%E7%A4%BA%E3%81%99%E6%95%B4%E6%95%B0%EF%BC%8E%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%AA%E3%81%91%E3%82%8C%E3%81%B0%20batch_size%20%E3%81%AF%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E3%81%A732%E3%81%AB%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%99%EF%BC%8E

　「batch_size」は勾配更新毎のサンプル数を示す整数であり、１回あたりの学習の大きさを示しているそうだ。一般的に以下の特徴が存在する。
１，バッチサイズを小さくする:
局所解に嵌りずらくなる。
GPU を使用する場合、計算効率が悪くなる。

２，バッチサイズを大きくする:
局所解に嵌りやすくなる。
GPU を使用する場合、一度に計算できたほうが計算効率がよい。
あまり大きい値にしすぎると、GPU のメモリに乗り切らない場合もある。

# ローカルでの検証

⓵デフォルト(32)の場合
```
log = model.fit(X_train, Y_train, epochs=5000, batch_size=32, verbose=True,
                callbacks=[keras.callbacks.EarlyStopping(monitor='val_loss',
                                                         min_delta=0, patience=100,
                                                         verbose=1)],
         validation_data=(X_valid, Y_valid))
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533364/5a76bc1d-34ff-6bd4-51f6-c7a5e4d3dc7e.png)

⓶batch_sizeを48に変更
```
log = model.fit(X_train, Y_train, epochs=5000, batch_size=48, verbose=True,
                callbacks=[keras.callbacks.EarlyStopping(monitor='val_loss',
                                                         min_delta=0, patience=100,
                                                         verbose=1)],
         validation_data=(X_valid, Y_valid))
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533364/2501cf48-8ba9-c343-112f-ff895839cd4c.png)

# GoogleColaboratory上の場合(batch_sizeが24)

```
log = model.fit(X_train, Y_train, epochs=5000, batch_size=24, verbose=True,
                callbacks=[keras.callbacks.EarlyStopping(monitor='val_loss',
                                                         min_delta=0, patience=100,
                                                         verbose=1)],
         validation_data=(X_valid, Y_valid))
```
```
              precision    recall  f1-score   support

           0       0.71      0.76      0.74        33
           1       0.89      0.87      0.88        77

    accuracy                           0.84       110
   macro avg       0.80      0.81      0.81       110
weighted avg       0.84      0.84      0.84       110
```

# 検証結果

　３つの結果を比べて、マシンの性能がディープラーニングを左右することが判明した。計算効率を重視するなら、バッチサイズを大きくすることだが精度は落ちる。逆はまたしかりということなのだろうか。
順列PをSwiftで書いただけの記事 その2

# はじめに

以前、順列PをSwiftで書いただけの記事を書きました。
順列とは、「1から4の数字が書いた4枚のカードの並べ方はいくつありますか（また、その並べ方は何か）」という問題で出てくるやつです。1, 3, 2, 4 や 2, 4, 3, 1 が順列。

https://qiita.com/samekard_dev/items/69b631e4c0991dab6446

前に書いたこの記事では要素数を指定したら全部を一気に返す仕様でした。例えば要素数が6なら720個返ってきます。

しかし、現在の状態から次のものへ変換する関数も需要があるのではと思い、（すでに存在すると思うが興味があって）作成しました。
次のものってなんだ、ということですが、
[1, 2, 3, 4]の次は[1, 2, 4, 3]
その次は[1, 3, 2, 4]
その次は[1, 3, 4, 2]
となります。
[1, 2, 3, 4]の状態でこの関数を実行すると[1, 2, 4, 3]に変わります。

# 仕様

124653から125346にするには

## 1.配列の後ろから見ていって下がったところを見つける

下がったところ（のインデックス）をkeyとする

![Permu1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46631/a8acf93b-b838-ddf6-f093-4b3f3f995148.png)

## 2.keyより右をひっくり返す

![Permu2-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46631/2ccde503-32f8-ad07-213c-1dae3b54a159.png)
![Permu2-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46631/e8aba589-db7b-96f8-4bd8-0a7072ac1d14.png)

## 3.keyより右を順番に見て、keyより大のものを見つける。それをkeyの値と交換する。

![Permu3-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46631/bb470f46-9111-ef0f-95bf-f10abe9dcfce.png)
![Permu3-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46631/7bd8d289-ff9d-7568-1699-147c06af67ec.png)

## 4. 完成

![Permu4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46631/247bf5e2-3451-3b1d-b525-05870bc6f5cb.png)

# 実装

inoutで渡しているので関数内で書き換えます。
次がある場合はtrueを返します。次がない場合はfalseを返します
初めの状態は 1, 2, 3, 4 のような昇順

```
import Foundation

func nextPermu(_ a: inout [Int]) -> Bool {

    guard a.count >= 2 else {
        return false //nextは存在しない
    }

    let last = a.count - 1
    
    //find key place
    var key = -1
    var right = a[last]
    for i in (0..<last).reversed() {
        if a[i] < right {
            key = i
            break
        }
        right = a[i]
    }
    guard key != -1 else {
        return false
    }
    
    /* 例 123654のとき
     last 5
     key 2
     順番交換範囲 3個
     順番交換インデックス 3から5
     */
    
    //keyより右をひっくり返す
    let turn = last - key //交換範囲
    /* 例
     turn1 交換作業なし
     turn2 交換作業1回
     turn3 交換作業1回（真ん中は必要なし）
     turn4 交換作業2回
     */
    
    for i in 0..<turn / 2 {
        let temp = a[last - i]
        a[last - i] = a[key + 1 + i]
        a[key + 1 + i] = temp
    }
    
    //keyより右で、初めにあるkeyより大きいものをkeyと交換
    for i in 1...last - key {
        if a[key + i] > a[key] {
            let temp = a[key]
            a[key] = a[key + i]
            a[key + i] = temp
            break
        }
    }
    return true
}

var a = [1, 2, 3, 4, 5, 6]

while nextPermu(&a) {
    print(a)
}

```
データベースのインデックスについて世界一ふわっと理解する


DBのインデックスを調べてよく出てくるのが、「本の索引のようなものです。」という例えである。
が、これだけでは全くピンとこず、幾度となく調べる手を止めてしまった。

インデックスという名前なのだから索引のようなものであるのは当たり前だろ！
インデックスを指定するとき、カラム名を指定するが、

* 指定したカラムが本の索引の何に当たるのか
* 登録するとどういう処理なのか

が全くピンと来ずに「だからインデックスってなんなんだよおおお」と何度も発狂した記憶がある。

今回、自分なりに納得の行く理解ができたのでまとめておく。

:::note warn
※大体はこの理解で問題はないはずだが、厳密には違う点が多々あるかもしれないことは予めご理解頂きたい。
:::

## 【インデックス無し時の索引について】

まず、インデックスがなぜ早くなるのかを理解するには、インデックスがない場合の索引の仕方を理解する必要がある。

インデックスがない場合、データベースは「フルテーブルスキャン」と呼ばれる処理を行い、各レコードの対象カラムを１つずつ確認して条件に一致するかどうかをチェックする。
そのため、インデックスがないと大量のデータを扱うには非常に時間がかかってしまう。
※データ量の少なく、多くなることがない場合は、インデックスと作るより早い場合もある。


## 【インデックスを作成するとどうなるか】

インデックスを作成するとき、大体はカラム名を指定して作成すると思うが、その時一体何が起きているのかを理解する。

インデックスを作成すると、インデックス用の別のデータ構造（よくB-treeと呼ばれる木構造）が作成される。
このデータ構造には
<font color="IndianRed">**指定したカラムの値と、その値がテーブルの何行目に存在するかという場所を示すポインタ**</font>
が指定したカラムでソートされた状態で保存される。

この指定した
<font color="IndianRed">**カラムの値とその場所をしめすポインタのデータ構造がインデックス**</font>
ということになる。

本の索引は、よく頭文字順で並んでいると思うが、例えの話をすると、
**「本」というテーブルに対して、「頭文字」という情報、カラムで作成したインデックスが、「索引」ページということになる。**


## 【インデックスを作成するとなぜ早くなるのか】

これまでの２つの情報からインデックスを作成するとどのような方法で探索を行い、早くなるのかを理解する。

これまでの情報をまとめると、
　インデックスを作らないと、テーブルを１件ずつ条件（WHERE句やJOIN句）に該当するかチェックしてしまう。
　インデックスを作成すると、インデックスに指定したカラムの値とその場所を示すポインタのデータ構造を作成する。
となる。

インデックスの作成されたテーブルだと、下記流れで探索を行うようになる。
　インデックスを使用してまず指定したカラムとその値が合致するポインタを見るける。
　そのポインタが指すレコードをチェックして残りのインデックスで指定していないカラムを確認して条件に合致するかをチェックする。

例えば、
* *{名前、年齢、性別、都道府県、市区町村}*

というカラムがあるテーブルに、
* *{年齢、都道府県}*

と指定してインデックスを作成したテーブルがあるとする。
すると、

* 年齢：20歳、都道府県：大阪府のデータは、22,33,43,55行目に存在する。
* 年齢：20歳、都道府県：東京都のデータは、17,26,38,65行目に存在する。
* 年齢：25歳、都道府県：東京都のデータは、20,23,48,59行目に存在する。

というデータ構造が作成されるイメージ。

そして、そのテーブルに対して、WHERE句で *{年齢：20歳、都道府県：東京都、性別：男性}* を指定して索引を行った際、インデックスを利用してまず、*{年齢：20歳、都道府県：東京都}* に一致する行のポインタを索引する。
そして索引して出た、17,26,38,65行目のレコードに対して、 *{性別：男}* に該当するかを確認する。
という流れになる。
そのため、全件を1レコードずつ確認するより高速でデータを索引する事ができる。


【インデックスとは「本の索引のようなものです。」】
---
以上を踏まえて、

**「頭文字」と言うインデックスを作成したのが本の索引で、**
**「頭文字」が「た」に該当するデータ群の**
**「ページ数(レコードのポインタ)」を見て1件ずつ確認する。**

ため、インデックスとは、「本の索引のようなものである。」と例えられている。

ここまで言ってくれないと私みたいな人間は理解できませんよ。

---

皆様はどうでしたでしょうか？
インデックスに対する理解が少しでも掴めたなら幸いです。

完全に理解するには、きっとB-tree、木構造、二分探索あたりをしっかりと理解する必要があるかと思いますが、それは自分で調べてください（笑）。

では、またいずれ。
Qiitaの書き方の簡易まとめ

自分の練習を兼ねた簡易まとめ

# 見出しは# (シャープ、半角空白)を最初に入れる
本文はそのまま書く。

# コード
コードを書くには```(バッククォート[@ + alt])で挟む
```
ここにプログラムコードなどを書く
```
言語:見出し語　を1つ目のバッククォートの後に書くと
```python:python_code.py
```python:python_code.py
と書いた
```

# 記号類
\*(アスタリスク)で挟むと*italic type*になる
\**で挟むと**太字**になる
その記号そのものを記すときには \
G検定 受験メモ　(2023年9月 #4)

# 概要
2023年9月9日のG検定を受験した。まだ結果は出ていないが、忘れないうちに受験内容についてのメモを残しておく。
なお、私は画像認識技術開発経験があるため、まったくの初学者ではないことに注意。

## 使用した参考書、模試、動画

- 参考書
  - 深層学習教科書 ディープラーニング G検定(ジェネラリスト)公式テキスト 第2版
    - 公式のテキストは少なくともおさえておいた方がよいと思い、購入した。技術進化が激しい分野なので、最新の版が出ていたらそちらを購入したほうがよい。

  - 最短突破 ディープラーニングG検定(ジェネラリスト) 問題集 第2版
    - Amazonのレビューを見て適度な難易度に思えたこと、無料模試の特典がついている点から購入。解説が充実しており理解しやすかった。また、付属の無料模試がとても有用だった。

- 模試
  - 上記問題集付属の無料模試
    →  120分で200問のオンライン模試で、難易度は本番と比較して同等～やや難（個人的な印象）。問題は変わらないが、繰り返し解いて復習できるのが良い。解説も丁寧でGood。

- youtube動画
  - [シミュレーションの世界に引きこもる部屋(G検定、DS検定関連がメイン)](https://www.youtube.com/@simulationroom999
)
  - 「G検定対策 シラバスの用語ベースで問題つくろう」シリーズ。本番の数日前に、念のために見ただけのつもりだったが、知らない単語がいくつも見つかりとてもタメになった。視聴するだけで強制的に単語が頭に入ってくるので、単語になじみができて勉強がはかどった。あと、ゆっくり実況動画系は見てて楽しい。

## 勉強期間
- 8/22～9/8（20～30時間ほど）

## ざっくり勉強記録
- 8/22～9/4
  - 初めに、公式テキストを一通り読み、付属の問題を解く。
    - 全体の雰囲気をつかむとともに、重要そうな単語を脳内インプットする（次見た時に「これ見たことある単語だ！」と思えるようにする）
  - 次に、問題集を解く。
    - 正解した問題であっても、それぞの選択肢について軽く調べる。
  - 同じ問題集を再度解く。(2周目)
    - 知識を定着しやすくするため、短期間で繰り返す。
    - 2周目も間違えた問題は、マニアックな問題でなければ出てきた用語を調べる。
  - 公式テキストを読みなおす。(2周目)
    - 問題集での出題のされ方をもとに、用語理解を深める。（同時に出題された単語との違いを意識しながら理解する）
- 9/5
  - 問題集付属のオンライン模試を受ける。
    - 本番の試験形式に慣れるとともに、この時点での自分の実力を把握する。
    - 全問の解説を読む。
- 9/6
  - オンライン模試を再度受ける。(2周目）
    - すでに正解がわかっている問題であっても、設問の文章と選択肢を読んで理解する。
- 9/7
  - youtube動画（シミュレーションの世界に引きこもる部屋）を見る。
    - 理解のおぼつかない単語や初見の単語のうち、気になるものは調べなおす。
    - 複数の媒体から同じ単語に触れることで、知識を定着しやすくする。
- 9/8
  - 気になる単語を調べなおす。
  - 生成系AIについて勉強してなかったことを思い出し、ネットをさまよう。 

## 試験問題について

- 合格率の高さ通り、全体的に素直な問題が多くやさしい部類の検定試験だと感じた。（事前に受けたオンライン模試がやや難しかったので、相対的にやさしいと感じた可能性もある）
- パーセプトロンなどの基礎的な技術や、世の中の利用実績の多い技術（例：CNN、RNN）に関する問題が多いと感じた。一方、先端技術（例：生成AI）に関する問題数は少なかったように思う。今後どうなるかわからないが、まずはテキストに書いてある基本的な内容、用語を理解して知識の地固めをするのが良いと感じた。十分得点源にできると思う。
- 社会実装や法律倫理関連の問題は、一般常識に沿って考えて回答すればよいケースもあった。設問を読むのは大変だが、知識がなくても解けるサービス問題である場合もあるので、多少時間をかけて読解するのが良いと感じた。
- 単語を知っているだけで解ける問題もあり、いわゆる丸暗記も点数稼ぎの手段としてはそれなりに有効だと思った。
- 問題数は多いが試験時間が長いので、時間は十分足りた。（2時間で191問）

## G検定を受けての所感
- 自分が業務でかかわった画像認識分野以外は初見の用語が多かったので、受験を通じて多少なりとも知識の底上げができた。
- 全部自費だったので、とにかくお金がかかるのがツライ（参考書代は仕方ないが、受験料がちょっと高めに感じた）。自費受験の人は、これ以上お金を使いたくないという気持ちをモチベーションに向けるのが良いと思う。
- せっかく受験したのだから、一発合格して合格者限定のセミナーに参加して元を取りたい。
 - ある程度知識を持った人なら10時間程度の勉強で十分合格はできそう。模試や問題集をやって足りない知識の穴埋めをしていく進め方。


## 受験結果(9/25追記)

無事に合格しました！
ただ、数理・統計の得点率が想定外に低く、何をどう間違えたのかすごく気になる。


メール抜粋
```
この度は、2023年9月9日（土）開催の JDLA Deep Learning for GENERAL 2023#4 を受験頂き、ありがとうございました。
下記の通り受験結果をお知らせ致します。

■合否結果
=================
【　合　格　】
=================
総受験者数　 3,309名
合格者数　　 2,390名

■シラバス分野別得点率（小数点以下切り捨て）
１．人工知能とは. 人工知能をめぐる動向. 人工知能分野の問題：100%
２．機械学習の具体的手法：95%
３．ディープラーニングの概要：100%
４．ディープラーニングの手法：95%
５．ディープラーニングの社会実装に向けて：100%
６．数理・統計：66%
７．法律・倫理・社会問題：89%

※総合得点率、設問個別の正解・不正解、本試験の合格ライン等は開示しておりません。あらかじめご承知おきください。
```
2023: Week 36 - C&BSCo 5-a-side / Preppin' Data / Tableau Prep

# Challenge Preppin'Data 2023:Week 36

## 概要
### 試合日ごとの累計数計算
トーナメントで取得した勝ち星数と最終的な数字を各レコードでもっています。こちらを各チーム＆プレイヤーごとに試合日での累計にデータを直します。

左がインプットデータで、右がアウトプットデータです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/c37b5a94-c3a9-a800-6dc2-34f48d43eafc.png)

## 問題のページ（英語）※ここからデータをダウンロード
https://preppindata.blogspot.com/2023/09/2023-week-36-c-5-side.html

## 出題者の回答のページ（英語）※動画あり
https://preppindata.blogspot.com/2023/09/2023-week-36-solution.html

## 自分の解決法

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/ecdca833-82eb-4ee6-06a4-2fb4722e62d4.png)

Step1　データを降順に並べて、累計します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/a825957c-4314-ffee-9612-f52f93ab0c63.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/aece69ef-0c6f-414b-d606-1de6c1ec14e3.png)

{ <font color="red">PARTITION [Team],[Player ID]:</font> <font color="#1e90ff">{ ORDERBY [Tournament Date]Desc:</font><font color="LightSeaGreen">(WINDOW_SUM([Matches Played in Tournament])</font>)}}

この式を日本語に訳すと、
[Team],[Player ID]ごとに、データを[Tournament Date]の降順で並べて、[Matches Played in Tournament]を集計していく

Step2　最終のスコアから、累計値を引きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/c5fcd525-9ad0-0205-55a7-244ec5bce1ad.png)
[Total Matches]-[Experience at beginning of Tournament]
STM32CubeIDEプロジェクトをPlatformIOにコピーする

ほぼ手作業で，思ったより簡単だったのでメモ。

- STM32CubeIDEでプロジェクトを作成
- ピン定義等を行って，`Generate Code` を実行しておく。
- PlatformIOでカラのプロジェクトを作成する。
- STM32CubeIDEのプロジェクトにあるソースファイル等をPlatformIOプロジェクトにコピーする。

以下の例では，

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/2fac7322-7d74-4b92-48c1-2a1d2f551e9e.png)

Core - Src にある *.c ファイルと，Inc 以下にある *.h ファイルを，

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/2a61067c-1be2-ffc4-3de1-9306a9b34990.png)

src フォルダーと include フォルダーにコピー。

- `platformio.ini` は適切に準備する必要があります。私の例では以下の感じです。

```platformio.ini
[env:nucleo_g070rb]
platform = ststm32
board = nucleo_g070rb
framework = stm32cube
```

Lチカ程度であれば，これでうまく動きました。提供されているライブラリー，ボード定義が基本は同じなのかもですね。

Driversフォルダーにライブラリーをおいたものが，PlatformIOではうまくコンパイル（正しくはリンク）できませんでした。基本的なことがわかっていないかもしれない。ですがとりあえずそれなりに便利に使えそうでした。

STM32CubeIDEは，ピン定義，クロック設定が簡単でいいですね。プロジェクトのリネームやコピーが少し面倒で，エディターがちょっと使いにくいです。

PlatformIOに持っていくひと手間が必要ですが，見やすくて使いやすいエディターで作業できるのはいいですね。
[リサーチ・メモ] JPQL特定カラム取得

## 背景
通常は、エンティティのすべてを取得していたが、大量データを扱う際には特定カラム取得となり、SQLとは違った記載方法だった為、メモとして纏める。

## 全カラムを取得する場合
```
<named-query name="findPersonsAddressInfo">
    <query>
        SELECT 
            p, a
        FROM 
            Person p 
        INNER JOIN 
            Address a
        ON
            p.addressId = a.addressId
        </query>
</named-query>
```



## 特定カラムを取得する場合
### 新規エンティティを作成する方法
新規エンティティを作成し、JPQLは今まで通りの記述をする。
### 既存エンティティにコンストラクタを追加する方法
※エンティティにマッピングする為のコンストラクタを追加し、JPQLにはカラムを指定しNEWを使用してマッピングする。
```
public class Person {
  //デフォルトコンストラクタ
  public Person(){
  }

  //特定カラム取得
  public Person(String name, int age){
    super();
    this.name = name;
    this.age = age;
  }
}
```
```
<named-query name="findPersonsAddressInfo">
    <query>SELECT NEW パス.Person( 
            p.name, p.age), a
        FROM 
            Person p 
        INNER JOIN 
            Address a
        ON
            p.addressId = a.addressId
    </query>
</named-query>
```
STM32F103C6 ボードで SSD1306 128x32 を Arduino I2Cで動かす

意外と情報を探すのに手間取ったのでメモ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/efd28801-6467-ead3-f5dd-c1a4936a4cc1.png)


```main.cpp
#include <Arduino.h>
#include <Wire.h>
#include <U8x8lib.h>

// - (add) PB8(SCL)/PB9(SDA) - SSD1306 128*32

U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_NONE);

void setup(void)
{
  Wire.setSCL(PB8);
  Wire.setSDA(PB9);

  u8x8.begin();
}

void loop(void)
{
  u8x8.setCursor(0, 0);
  u8x8.setFont(u8x8_font_8x13B_1x2_f);
  u8x8.println("Boot F103C6");

  u8x8.clear();
}
```

```platformio.ini
[env:genericSTM32F103C6]
platform = ststm32
board = genericSTM32F103C6
framework = arduino
lib_deps = olikraus/U8g2@^2.35.5

upload_protocol = stlink
```

安く手に入ったボード，せっかくなので 128x32 の表示機を添えて，ガシガシはんだ付けで配線して使えるように作成中でした。

# STM32 + ArduinoでI2Cのピンアサインを変える

genericSTM32F103C6 ですと SCL が PB6 SDA が PB7 が前提です。PB8 と PB9 に配線したので，`main.cpp` でピン定義を変更しました。

```cpp:main.cpp（抜粋）
  Wire.setSCL(PB8);
  Wire.setSDA(PB9); // これを実行した後に u8x8 を初期化
  u8x8.begin();
```

# u8x8定義

ピン定義を変更した上で，STM32ではI2C1に接続しましたので，

```cpp:main.cpp（抜粋）
U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_NONE);
```

で普通に使えました。