OmniAICreator/Qiita-1.07M huggingface dataset:
Reactを基本からまとめてみた【29】【Fragment】

```react
import React from "react";

const SampleComponent : React.FC = () : JSX.Element =>{
    return (
        <div>Mars</div>
        <div>quai</div>
    )
}

//[Error] JSX expressions must have one parent element.
```
Reactではコンポーネントとして複数の要素を返したい場合、以下のようにそのまま書くことができない。このエラーを回避するために、複数の要素を入れる場合には必ず一つのタグの中に入れる必要がある。

divタグで囲む方法もあるが、Reactにはこのような場合のためにFragmentというタグが用意されている。

Fragmentタグは、機能を持たないタグで、以下のように複数タグをJSXで返したい場合に使用する。

```react
import React from "react";

const SampleComponent = ()  =>{
    return (
        <React.Fragment>
            <div>Mars</div>
             <div>quai</div>
        </React.Fragment>
    )
}
```

コンポーネントの返し値として以外にも、map()関数で複数要素を返したい場合にもよく使います。

```react
const SampleComponent = ()  =>{
    return (
        <React.Fragment>
            {sampleArray.map((i, key) => {
                return (
                    <React.Fragment key={key}>
                        <div>Hello!!</div>
                        <div>{i}</div>
                    </React.Fragment>
                )
            })}
        </React.Fragment>
    )
}
```

map()関数で返している要素の中でFragmentにkeyをpropsとして渡す。
keyはFragmentが受け取れる唯一のpropsです。


```react
const SampleComponent = ()  =>{
    return (
        <>
            {sampleArray.map((i, key) => {
                return (
                    <React.Fragment key={key}>
                        <div>Hello!!</div>
                        <div>{i}</div>
                    </React.Fragment>
                )
            })}
        </>
    )
}
```
Fragmentは空のタグ<></>として書くことができる。
##### ※ keyを渡す場合には空のタグは使えないことに注意。

#### メリット：セレクターの指定

FragmentはHTMLにレンダリングされる際には存在しない仮のメソッドで、
FlexboxやGridなどのCSSスタイルを利用する際に、構造を壊さず利用できる。


## 参考サイト
[【React】Fragmentの利用方法・メリットについて詳しく解説](https://marsquai.com/745ca65e-e38b-4a8e-8d59-55421be50f7e/f83dca4c-79db-4adf-b007-697c863b82a5/2bc34da4-3f8c-4b46-8e10-b016dbcb89bb/)
AWSからGoogleへのドメイン移管

保有しているドメインがAWSにあるのですが、Googleに移管しようと思い、Google で申し込んだところ、認証コードを教えろ、と言われました。

AWS の R53 に行って、「登録済みドメイン」をクリックすると、以下のように出てきます。
ここの、「認証コード」の「コードの取得」をクリックしてその値をコピーして、Google の画面で入力すると、Google 側で処理（AWSに連絡して移管するぞー、と号令をかけるようです）が始まります。どうやら、10日程度はかかるようです。

![dns_change.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/470368/29290c42-5be2-3c76-2fcd-3775fea5f6f8.png)

上記は、AWS の R53 の画面となりますが、Google Domains の方では、以下のようになっています。

![dns_change_google.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/470368/6e989f39-6e31-f19b-3cbb-1337107858a2.png)
git mergeしたらnot something we can mergeが出たので解決してみた

今回はgit mergeを実行しようとした以下のエラーが発生した

```
merge: sigh-up - not something we can merge
```

<h1>解決策</h1>
<h3>ブランチ名をコピペしたらいけた。</h3>
ブランチを確認して、マージしたいブランチ名をここでコピーします。
```git
git branch
  filling-in-layout
* main
  modeling-users
  rails-flavored-ruby
  sign-up
  static-pages
```

コピーしたマージ名をペーストしてあげると解決できました。
```
git merge <マージ名> #マージ名を入力するときだけペーストする。
```
<h2>考えられる原因</h2>
おそらくタイプミスなのですが、ぱっと見はよくわかりませんでした。なので、この手のエラーが出たらとりあえずブランチ名をコピペしてみるといいかもしれないです。
【初心者向け】【AWS SAA合格へ向けて】AWSにおけるネットワークの概要について

## 概要
AWS SAA合格へ向けてAWSについて１から勉強した際に学んだことを定期的にアウトプットしたいと思います
今回は
- Region(リージョン)
- VPC(バーチャルプライベートクラウド)
- AZ(アベイラビリティゾーン)
- パブリックサブネットとプライベートサブネット
- IGW(インターネットゲートウェイ)
- ルートテーブル
- NACL(ネットワークアクセスコントロールリスト)とSG(セキュリティグループ)の違い
- 踏み台サーバとNATゲートウェイ

について説明したいと思います
図に表すと以下のようになります
![network.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625980/84aa5369-af6c-6588-f89b-507bb1b81e1d.png)

## Region
AWSのサービスを提供している地域のことで日本では
- 東京リージョン(ap-northeast-1)
- 大阪リージョン(ap-northeast-3)
 
の2種類のデータセンターが存在しますが基本的に東京リージョン(メインリージョン)を使用します
大阪リージョン(ローカルリージョン)は災害復旧対応などの緊急時に使用されます
基本的にリージョン同士は災害に備えて物理的に離れていてかつ独立しています
(ただし、隣接しているリージョン間は広帯域の専用ネットワークで接続されているのでデータのやり取りはできます

## VPC
AWS上の仮想ネットワークのことです
Region内に作成します
よく設定するVPCのプライベートIPアドレスのレンジは10.0.0.0/16です
CIDRが16なので最大65536個のIPアドレスが利用可能です

## AZ(アベイラビリティゾーン)
各リージョンに存在するデータセンターのことです
VPC内に作成します
東京リージョンで利用できるAZは
- ap-northeast-1a
- ap-northeast-1c
- ap-northeast-1d

の3つです

## パブリックサブネットとプライベートサブネット
CIDRで分割したVPCの論理的なネットワークです
AZ内に作成します
VPCが10.0.0.0/16なので例えば
- パブリックサブネットは10.0.1.0/24
- プライベートサブネットは10.0.2.0/24

のようにのVPCのCIDRの範囲内で設定するのが一般的です

### パブリックサブネットとプライベートサブネットの違いは？
インターネットと通信したいインスタンス(アプリケーションなど)はパブリックサブネットに、
インターネットと通信せずにインスタンス(RDB)はプライベートサブネットに配置します

## IGW(インターネットゲートウェイ)とルートテーブル
### IGW
VPCとインターネット間の通信を可能にする仕組みです
サブネットにIGWがないとプライベートサブネットになってしまうのでインターネットと通信したい場合は必須です

## ルートテーブルとは？
関連付けされているサブネットのネットワークトラフィック(インバウンドとアウトバウンドトラフィック)を制御するためにルーティング規則のことです
ルートテーブルを通るトラフィックをIPアドレスで判断してIGWに送るかローカル上の別インスタンスに送るかなどの判断をします

## NACL(ネットワークアクセスコントロールリスト)とSG(セキュリティグループ)
### NACL
サブネットのインバウンドとアウトバウンドトラフィックを制御するためのファイアウォールとして機能する任意指定のセキュリティレイヤーです

### SG
EC2インスタンスの仮想ファイアウォールのことです
後述するNACLと一緒に出題されるので注意

### NACL(ネットワークアクセスコントロールリスト)とSG(セキュリティグループ)の違い
NACLのインバウンドとアウトバウンドルールはステートレス(状態を持たない)なのに対してSGはステートフルです(状態を持つ)
例えばNACLでインバウンドルールを設定したルールは同様にアウトバウンドルールも設定する必要があリます
対してSGはインバウンドルールを設定したら同様のルールはアウトバウンドでも自動的に適用されます

## 踏み台サーバとNATゲートウェイ
### 踏み台サーバ
インターネットからプライベートサブネット内のインスタンスへ接続する際に経由するインスタンスです
プライベートサブネットへインターネットからアクセスできないため、パブリックサブネット内に踏み台サーバを用意して経由します

### NATゲートウェイ
プライベートサブネット内のインスタンスからインターネットゲートウェイへ返信する際に経由するのがNATゲートウェイです
NATゲートウェイはインスタンスのプライベートIPアドレスをパブリックIPアドレス(ElasticIP)に変換してインターネットゲートウェイと連携します

## まとめ
最初は用語が多くてどれがどれかわからなくなりそうでしたが図にするとだいぶわかりやすくなってすんなり覚えられました

## 参考
https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html

https://hirotanoblog.com/aws-vpc/6757/
デイトラ「Web制作コース」　受講内容をアウトプット 13日目

学んだことをアウトプットしています。完全に自己満足ですので悪しからず。
以下の点を確実にアウトプット
①何で学んでるか
②日々の学習内容
③学びのポイント
④制作物
⑤+αで参考にした記事
⑥+αでやってみたこと

①デイトラ「Web制作コース初級編」　自力でBootstrapサイトの作成
②　Bootstrapを使って簡単なｻｲﾄの作成　復習＋α
　　⇒・10日目の復習完了。
　　　・11日目の復習完了。
　　　・12日目の復習完了。
③なし
④簡単なｻｲﾄの作成
⑤　ローカル環境でのフォントの読み込み方法
　　https://www.softel.co.jp/blogs/tech/archives/3676
⑥なし
エンジニアになりたい人へ：Webサーバーについて知ろう！

未経験からエンジニアになりたい人は、プログラミングから始める人が多いと思いますが、
エンジニアの仕事は、プログラミングだけではありません。そして、プログラミングだけでは、エンジニアになれません。同時にプログラミングが苦手でも、システム構成や開発の流れを理解するとエンジニアに近づきます！

![インスタスライド_202212317.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/b7b33c94-f16a-ffb2-7963-3048a0a3cb2e.gif)

# プログラミングしてみたけどこれはどうやって動いてる？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/d26c7fb7-80dc-6ea0-7dbe-89881e4c9663.png)

## アクセスの仕組み
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/b894fd1f-afa9-6f63-a411-2473063b6794.png)
URL（アドレス）からインターネット上のWebサーバーにアクセスして情報を取得してます

## Webサーバーの中
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/f72c21b2-4553-e425-1701-88f5f9f2a369.png)
Webサーバーの中でプログラムが動いて結果を返しています。

## URLの仕組み
- インターネット上で公開されている個々の情報を指定するもの
- 「Webサーバ」と「インターネットの構造」に深く関係する情報を持つ
- 「http://www.yahoo.co.jp/index.html」　などと記述する

## まとめ
１．スマホやPCから、URL（アドレス）でサーバーに接続して情報を取得している
２．プログラムはWebサーバーで動く
３．URLはインターネット上でのサーバーの住所みたいなもの
エンジニアの仕事は、プログラミングだけではありません。そして、プログラミングだけでは、エンジニアになれません。同時にプログラミングが苦手でも、システム構成や開発の流れを理解するとエンジニアに近づきます！
プログラミング以外の事も勉強しましょう！

# 最後に
未経験の皆さん、若手エンジニアの皆さん、勉強方法について悩みがあればなんでも気軽に質問して下さい！
これからも記事を書いていきますので、モチベーションアップのためフォロー、イイねお願いします。
IIoTって知っていますか？

# はじめに
毎週1本様々な技術に関する記事を投稿しています。
もし興味のある方は下のリンクから他の記事も見ていただければ幸いです。
 [@7_inai_](https://qiixta.com/7_inai_)

# IIoTとは
IIoTとは、Industrial Internet of thingsの略称で、__産業用途に特化した[IoT](https://qiita.com/7_inai_/items/f2a56498b70b39befa0b)__ を意味しています。具体的には、産業用機械や装置・設備・システム等をネットワークで相互接続し、現場作業の効率化や見える化に使用されます。

# IoTとIIoTの違い
IIoTはIndustryに特化したIoTであるため、__IIoTはIoTの一種__ であると言えます。また、Industryに特化するため、プライベートやバックオフィスで使用するIoTとは違った特徴があります。その主な特徴は以下の通りです。
- 常時稼働
- 安定性
- 堅牢性
- 高度なアクセスレベル制御
->部外者やランクの低い社員がIoT内のネットワークにアクセスできないようにする
- 高品質なネットワーク帯域

# 工場 × IIoT
製造業の中心である工場にとって、IIoTは必要不可欠な要素となっています。特に __IIoTによる見える化__ は工場にとって非常に重要です。見える化を行うことで、不良率、出来高達成時間、ボトルネック、排出数の多い項目や製造ラインをリアルタイムで把握することができます。私も工場での勤務経験がありますが、`ボトルネックとなるラインや排出要因は日々変動します。それらを即座に把握し、重点的に人を投入して原因解析に取り組むことは製造ライン全体を安定化させるために非常に重要`です。

# SCM × IIoT
工場だけでなく、サプライチェーン全体を管理するためのIIoTの活用も重要です。サプライチェーンには必ずボトルネックがあります。それは、原材料の調達や人員の不足の場合の可能性もあれば、倉庫の在庫率の可能性もあります。また、急なトラブルで製品の自主回収等の不足の事態が発生した場合、__サプライチェーン全体を管理することは非常に困難__ です。そこで生かされるのがIoTです。`サプライチェーンの各工程の状況を一元的に管理することで、経営陣が即座に判断を下す必要があるときに非常に有効`です。

# 終わりに
DX、スマートファクトリー、Industry4.0等、製造業におけるホットワードはいくつもありますが、これら全てにIoTは絡んでいます。それだけIoTは重要な要素であり、これからの製造業においては必要不可欠な技術となります。私が以前勤めていた工場でも、IoT化は掲げられていましたが、各部署単位での導入が先行しており、部門どうしや他の工程とのつながりはほぼありませんでした。こういったIoT化とは違い、本来理想とされるIoT化を実現するためには、全社的に進める必要があるため非常に難易度が高いです。しかし、それだけ実現させた時の効果は大きく、IoT化によりできるようになることも多岐に渡ります。かつて日本のお家芸と言われていたような強い製造業を取り戻すためにも、IoTが非常に重要な要素となるでしょう。



最後までお付き合いくださりありがとうございました。
HTTP通信の流れ


# HTTPとは

HTTPは、Webサーバーと通信を行うときのプロトコルです。

WebはブラウザからWebサーバーにリクエストを投げてレスポンスを得るシステムですが、このとき通信の仕組みを支えているのがHTTPです。

HTTPはTCP/IPがベースとなっています。TCP/IPはインターネットで通信するときのプロトコルです。


# HTTP通信の流れ


ブラウザとWebサーバー間の通信の流れはざっくりと以下のようになっています。


```
DNSによる名前解決
TCPによるコネクションの確立
リクエストとレスポンス
```


### DNSによる名前解決

まず指定されたURIに関してDNSによる名前解決を行います。これによってリクエスト先を特定します。

具体的には、FQDN(ホスト名+ドメイン名)に該当するIPアドレスを取得します。
FQDNは、URIのうちの例えば、`www.hogehoge.com`のような部分です。

DNSサーバーと通信して`www.hogehoge.com`のIPアドレスを取得します。



### TCPによるコネクションの確立

続いて取得したIPアドレス先に対してTCPコネクションを確立します。

３ウェイハンドシェイクという手法を用いて「通信してもいいですか」「いいですよ」「わかりました」みたいなやりとりをします。



### リクエストとレスポンス

コネクションが確立できたら、リクエストデータを送信します。
リクエストに応じて、レスポンスデータを返されます。

TCPによってデータ伝送時も送達確認がなされます。
データ量が多い場合はパケットを分けて送信します。
```
レスポンス「１つ目のパケットだよ。」
リクエスト「１つ目のパケットが届いたよ。２つ目を送って。」
レスポンス「２つ目のパケットだよ。」
リクエスト「２つ目のパケットが届いたよ。３つ目を送って。」
```
みたいなイメージのやりとりをします。


# まとめ

ブラウザとWebサーバーの通信はHTTPで行う。

HTTP通信のざっくりとした流れは、
```
DNSによる名前解決
TCPによるコネクションの確立
リクエストとレスポンス
```
となります。


<br>
<br>


以下余談。
「Webサーバー」は「Webサーバーソフトウェア(Nginxなど)が起動しているコンピュータ」のことです。（`NginxイコールWebサーバ`などと理解しているとネットワークの学習をしているときによくわからないことになります。）

DNSで名前解決した`www.hogehoge.com`のIPアドレスは「Webサーバーソフトウェア(Nginxなど)が起動しているコンピュータ」の住所です。そのコンピュータまでパケットが渡ったら、「80番のアプリケーション宛ですよ」と言った感じでポート番号で識別して「Webサーバーソフトウェア(Nginxなど)」にパケットが渡されます。
HTMLの書き方

HTMLの動かし方
【参考】1冊ですべて身につくHTML&CSSとWebデザイン入門講座, SB Creative


<h5>HTMLの構成</h5>
 HTMLは大きく分けて、ページの構成を形作る「大きなタグ」と大きなタグの中で具体的にページを形にする「小さなタグ」の２要素でページを作るマークアップ言語である。
以下はあくまで具体例であり、このように分けなければならないというわけではない。


<br><h4>ページ構成の例<h4>
イメージ写真
![screenshot.2023-01-03 (9).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850098/f085010d-4346-eaa2-c20c-3ae569197b13.jpeg)

<br>上の写真のように大きくmainやarticle、sectionなどのタグを使ってページの構成を決める。

```HTML:ページレイアウト.html
<!--!DOCTYPEから</head>までは決まり文句みたいなもの-->
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title>サイトのタイトル(ブラウザのタブに出る名前)</title>
        <meta name="description" content="サイトの軽い紹介">
    </head>

<!--headerという大きいタグでページを構成->
<header>
    <!--h1という小さなタグで具体的にページを形作る-->
    <h1>ページタイトル</h1>
    
  <!--navという大きなタグでページを構成-->
  <nav>
    <!--ulとliという小さなタグで具体的にページを形作る-->
    <ul>
      <li>メニュー１</li>
      <li>メニュー２</li>
      <li>メニュー３</li>
    </ul>
  </nav>
</header>

<!--mainという大きなタグでページを構成-->
<main>
    <!--articleという大きなタグでさらに細かくページを構成-->
    <article>
        <!--h2という小さなタグで具体的にページを形作る-->
        <h2>書きたい内容</h2>
    </article>

    <!--sectionという大きなタグでさらに細かくページを構成-->
    <section>
        <!--h2という小さなタグで具体的にページを形作る-->
        <h2>書きたい内容</h2>
    </section>
</main>

<!--asideという大きなタグでさらに細かくページを構成-->
<aside>
   <!--h2という小さなタグで具体的にページを形作る-->
   <h2>書きたい内容</h2>
</aside>    


<!--footerという大きなタグでページを構成-->
    <!--ulとliという小さなタグで具体的にページを形作る-->
    <ul>
        <li>footer1</li>
        <li>footer</li>
    </ul>
<footer>
    
</footer>
```
<br>
<br>

※ただし、HTMLのみの記述だと下の写真のようになる。
あくまでHTMLはページの構成と具体的な記述内容を形成するだけであり、具体的なデザインはCSSやJavaScriptを使用する。
![screenshot.2023-01-03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850098/c13cedfc-1487-b860-79c4-18938f95fb8e.jpeg) 

そしてその構成を基に、実際に記述したい内容を小さなタグを使って書いていくのである。
<br>ここでは少しだけ例を紹介する。
<h5>例</h5>

| タグ名       |  効果        |
|:-----------:|:------------:|
| h1~h6タグ | 見出しを表示させる。太字になる。数字が小さくなるほど文字も小さくなる。 |
| pタグ | 文章を書くときに使う。太字にならない。 |
| aタグ |リンクを挿入するときに使う。|
|a href="URL"| aタグの具体例。URLを挿入するときに使う。|

このようにHTMLではページの構成と具体的な内容を記述するものである。しかし、デザインなどを適用させたい場合はCSSの記述が必要である。
【Android】Firebaseを使っていて、Could not deserialize object...エラーが発生した時の解決方法

# エラーが発生した当時の環境

Firestoreに保存されているドキュメントを取得する際に、`toObject()`を呼び出してドキュメントをデータクラスのインスタンスに変換しようとしました。

その時に使用したのが、以下の内容の`Member`データクラスです。プロパティとして、`String`型や`DocumentReference`型に`Timestamp`型など、Firebaseを使う方にはお馴染みの内容かと思われます。

```kotlin
data class Member(
    val id: String = "",
    val name: String = "",
    val groupRef: DocumentReference,
    val imageRef: DocumentReference? = null,
    val createdAt: Timestamp = Timestamp(Date()),
)
```

そして、いつものように取得した`DocumentSnapshot`インスタンスの値に対して`toObject()`を呼び出して、定義したデータクラスのインスタンスにデシリアライズを行おうとしました。

```kotlin
val documentReference = firestore.collection("members").document("member-id-1")
val snapshot = documentReference.get().await()

val data = snapshot.toObject<Member>()?.copy(
    id = snapshot.id
)
```

# Could not deserialize object...エラーの発生

上記の処理を実行したら、次のようなエラーが発生しました。

```shell
E  java.lang.RuntimeException: Could not deserialize object. Class com.takagimeow.xxx.core.service.model.Member does not define a no-argument constructor. If you are using ProGuard, make sure these constructors are not stripped
```

# Could not deserialize object...エラーの発生箇所

`Log.d()`などを配置して、順を追って調べていくと、なんとエラーの原因が`snapshot.toObject<Member>()`の呼び出しであることが判明しました。

```kotlin
return snapshot.toObject<Member>()?.copy(
    id = snapshot.id
)
```

ただ、問題の原因はこの`toObject<Member>()`の呼び出し事態ではありませんでした。

実は、この`Member`データクラスのコンストラクタの定義自体に問題があったのです。

# toObject()に渡すデータクラスを定義する際の注意点

コンストラクタの部分をよく見ると、`groupRef`プロパティにだけ、初期値が設定されていないことがわかると思います。

```kotlin
data class Member(
    ...
    val groupRef: DocumentReference,
    ...
)
```

Kotlinのデータクラスを定義した場合、引数のないコンストラクタは自動的に作成されません。

前提知識として、Android用のFirebase SDKでは、`DocumentSnapshot`インスタンスの値に対して`toObject<T>()`を呼び出すことで自動的にデシリアライゼーションが行われます。

そのため、`toObject()`に使用するデータクラスの定義時には、**引数なしでコンストラクタを呼び出しても大丈夫**なように**各プロパティに対して初期値を指定**してあげる必要があるのです。

このとき、データクラスのすべてのプロパティには、`null`もしくは型に対応した適切な値を初期値として渡します。

もし初期値を設定しない場合は、デシリアライゼーションの機能が使えなくなってしまうため、`toObject()`呼び出しが失敗します。そして、その失敗の原因として`Could not deserialize object...`エラーが発生することになります。

# データクラスのすべてのプロパティに初期値を設定する

修正した`Member`データクラスは次のようになります。

```kotlin
data class Member(
    val id: String = "",
    val name: String = "",
    val groupRef: DocumentReference? = null,
    val imageRef: DocumentReference? = null,
    val createdAt: Timestamp = Timestamp(Date()),
)
```

この修正のおかげで、無事エラーの発生は解消されました。

# まとめ

Android用Firebase SDKを使う際は、データクラスの定義時に必ず初期値を渡すことをこころがけながら開発することを強くおすすめします。さもないと、自分のように解決までに無駄な時間を費やしてしまうことになるかもしれません・・・

# 参考にした記事

https://stackoverflow.com/questions/66844341/could-not-deserialize-object-class-does-not-define-a-no-argument-constructor-if

https://qiita.com/morayl/items/c14741ebf17b7c9e4e8b#%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E6%9B%B8%E3%81%8D%E8%BE%BC%E3%81%BF
distroless node18 でshellでログインしてnodeコマンドを実行する 

ソースはdistrolessのexamples
https://github.com/GoogleContainerTools/distroless/tree/main/examples/nodejs


debugタグのイメージを利用する。
```
FROM gcr.io/distroless/nodejs18-debian11:debug
```

entrypointにshを指定してログインする。
```
docker run -p 8000:8000 --entrypoint=sh -it  local/node-distroless-http
```

backendで実行してみる。
```
 /nodejs/bin/node hello_http.js &
```

URLにアクセスする。
http://127.0.0.1:8000/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3084139/dcd1169b-e5a9-99cb-b3d1-e61f531dfd39.png)


参考にさせていただきました。
https://qiita.com/taquaki-satwo/items/f8fbe8b1efc4b2323ae7
2023/1/3主にITとかセキュリティの記事

2023年、ビットコインとエネルギーをめぐる「恐怖・不確実性・疑念」は終わる【コラム】(1/2)
https://www.coindeskjapan.com/169887/

2023年の暗号資産：10の予測(1/1)
https://www.coindeskjapan.com/169218/

2022年、ハッキング被害額が過去最悪──2023年に向けた対策とは(12/31)
https://www.coindeskjapan.com/169490/

「学ばない日本人」にリスキリングを浸透させるには(1/2)
https://www.nikkei.com/article/DGXZQOUC207OX0Q2A221C2000000/

仮想通貨、不信がもたらす発展の阻害 シンガポールのカプロン氏(1/2)
https://www.nikkei.com/article/DGXZQOFL00022_Y2A221C2000000/

Windows 11が増えるもWindows 10が4倍以上、12月デスクトップOSシェア(1/1)
https://news.mynavi.jp/techplus/article/20230101-2551545/

PDFファイルをExcelファイルに変換する方法(1/2)
https://news.mynavi.jp/techplus/article/20230102-2552145/

Webサイト1月CMSシェア、WordPressの増加とShopifyの減少(1/1)
https://news.mynavi.jp/techplus/article/20230101-2551549/

1月WebサイトLinux向けシェア、Debianが増加(1/2)
https://news.mynavi.jp/techplus/article/20230102-2552057/

｢インターネット公共圏｣は自由と民主主義を取り戻せるか。欧州の個人主義から考える｢ソーシャル｣の本質(1/2)
https://www.businessinsider.jp/post-263878

自分のハンドルネームがネットのどこで使われているかがわかる「HandleFinder」(1/2)
https://gigazine.net/news/20230102-handlefinder/

学習データに最適化されすぎて本来の目的が達成できなくなる「過学習」と同様の現象はAIだけでなく社会全体で起こっているという主張(1/2)
https://gigazine.net/news/20230101-overfitting-machine-learning-goodharts-law/

ウェブはスイスではなくフランスで発明された(1/1)
https://gigazine.net/news/20230101-web-was-invented-in-france-not-switzerland/

年明けだ！ 2023年に実施されるパッチチューズデーのスケジュールをチェックしよう
来年も「パッチチューズデー」は継続、日本向け配信は第2水曜日または第3水曜日(1/1)
https://forest.watch.impress.co.jp/docs/serial/yajiuma/1466871.html

2023年に有望なテクノロジー3選--ITプロフェッショナルにとっての「ABC」(1/2)
https://japan.zdnet.com/article/35197899/
vscodeでimportが自動でソートされるのを無効化する(Mac)

# はじめに
こんにちは。takumikanです。

MacでVSCodeを使用していた際に、
importの順番が自動的にソートされてしまうことがあり、
色々と不便だったので、無効化する方法を個人的にメモしておきます。
(何回か調べてたどり着いたので...)

# 手順
1. VSCodeの設定を開き、"**code action**"で検索
    1. まずはVSCodeを開く
    1. `cmd+,`でSettingを開く (以下のような画面になる)
        <img width="600" alt="open vscode setting" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2515824/d0e48450-f20c-02fa-f058-f089dae6fd56.png">
    
    
    2. "Search Settings"の部分で"**code action**"で検索(以下)
        <img width="600" alt="serach code action" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2515824/12ebeda7-27cd-c066-178b-1d4768ef5466.png">

2. setting.jsonを書き換える
    1. "**Edit in settings json**"の部分をクリック(以下)
        <img width="600" alt="opt setting json" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2515824/4f4c7475-35eb-f01f-1904-45bf3e2e64be.png">
    2. 以下の"**true**"の箇所を"**null**"に変更する
        2. ちなみにデフォルトでは**null**なのでいつしかに設定していたのであろう...
        2.  <img width="600" alt="sort setting json" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2515824/cd235b26-bd5d-9e1e-d7e4-fe2ddd334889.png">

# まとめ
今回は、vscode上でimport順序が自動でソートされる設定の無効化を書きました。
調べていると色々な方法がヒットしたので、誰かの役に立つことを願っています...
zsh compinit: insecure directories, run compaudit for list. を解決した

## はじめに
- macbookで別アカウントのアドミンユーザを作成したところ、元のアドミンユーザにて以下のエラーが警告文が発生してしまった。
```
zsh compinit: insecure directories, run compaudit for list.

$ compaudit
There are insecure directories:
/usr/local/share/zsh/site-functions
/usr/local/share/zsh
```
- このメッセージは新規ターミナルを開いた際に毎回出てきてしまい、なんとか消したい気持ちだった。

## やったこと
- こちらの記事を参考に実行してみましたが、変わらず。

https://qiita.com/ayihis@github/items/88f627b2566d6341a741

- brew doctorを試してみた。
```
$ brew doctor

Warning: The following directories are not writable by your user:
/usr/local/share/aclocal
/usr/local/share/doc
/usr/local/share/info
/usr/local/share/locale
/usr/local/share/man
/usr/local/share/man/man1
/usr/local/share/man/man3
/usr/local/share/man/man5
/usr/local/share/man/man7
/usr/local/share/man/man8
/usr/local/share/zsh
/usr/local/share/zsh/site-functions
/usr/local/var/homebrew/linked
/usr/local/var/homebrew/locks

You should change the ownership of these directories to your user.
  sudo chown -R $(whoami) /usr/local/share/aclocal /usr/local/share/doc /usr/local/share/info /usr/local/share/locale /usr/local/share/man /usr/local/share/man/man1 /usr/local/share/man/man3 /usr/local/share/man/man5 /usr/local/share/man/man7 /usr/local/share/man/man8 /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var/homebrew/linked /usr/local/var/homebrew/locks

And make sure that your user has write permission.
  chmod u+w /usr/local/share/aclocal /usr/local/share/doc /usr/local/share/info /usr/local/share/locale /usr/local/share/man /usr/local/share/man/man1 /usr/local/share/man/man3 /usr/local/share/man/man5 /usr/local/share/man/man7 /usr/local/share/man/man8 /usr/local/share/zsh /usr/local/share/zsh/site-functions /usr/local/var/homebrew/linked /usr/local/var/homebrew/locks
```

## 解決方法
- 上記の`$brew doctor`でも分かる通り、`/usr/local/share/zsh /usr/local/share/zsh/site-functions `の権限が新規ユーザに移ってしまったと考えられるので、オーナーとパーミッションを変更する。
```
$ sudo chown -R $(whoami) /usr/local/share/zsh /usr/local/share/zsh/site-functions

$ chmod u+w /usr/local/share/zsh /usr/local/share/zsh/site-functions
```

- これで無事に解決しました。
M1グランプリの審査結果を主成分分析する

遅ればせながらM1グランプリの審査結果を主成分分析します。
各審査員が各演者をどう評価したかを分析することで、演者・審査委員双方の特徴を垣間見ることができます。
全文を通じて敬称略です。

ソースコード：
https://www.kaggle.com/code/kotamori/m1-grand-prix-2022

＊本文中のコードはイメージです。そのままでは動きません。

## データ

データはこちら。行に演者、列に審査員を並べた行列データです。
![Screenshot_2023-01-03_00-45-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80588/51bf6434-9e61-95c7-baad-d46ba1299c8c.png)
## 審査員間の順位相関

(ナイツ塙、サンド富澤、立川志らく) の3名と (中川家礼二、松本人志)の2名は特に相関が強い。関東と関西で分かれている感じが面白い。山田邦子は特に松本人志と博多大吉との相関が低い。
相関にばらつきがあるものの、負の相関がないので、評価軸が異なることはあっても好みが反対ということはないらしい。

```python
cor = x.corr("spearman")
cor[cor==1] = None
sns.heatmap(cor, annot=True, fmt=".2f", cbar=False)
```
![Screenshot_2023-01-03_00-47-55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80588/78b934b7-1f12-6218-1551-acee998b4215.png)

## 主成分分析

審査員ごとに平均０，分散１に基準化してから主成分分析を行います。
```python
p = Pipeline([
  ("scale", StandardScaler()),
  ("pca", PCA())
])

res = p.fit_transform(x)
```

### 分散の説明力

```python
fig, ax = plt.subplots(figsize=(6, 4))
ax.grid()
ax.plot(p.steps[-1][-1].explained_variance_ratio_, marker="p")
ax.plot(p.steps[-1][-1].explained_variance_ratio_.cumsum(), marker="p")
```
最初の２成分で分散の80％ほどを説明できるようです。
![Screenshot_2023-01-03_01-03-26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80588/36aa27ad-d393-9fa9-08ef-638f6efb604d.png)

### 第1、第2主成分

```python
fig, ax = plt.subplots(2, 1, figsize=(7, 8))
a = ax[0]
a.grid()
a.scatter(res[:,0], res[:,1])
for idx, pos in zip(x.index, res):
  a.text(pos[0], pos[1], idx)
mx = max(abs(res[:,0]))*1.1
a.set_xlim((-mx, mx))
mx = max(abs(res[:,1]))*1.1
a.set_ylim((-mx, mx))

comps = p.steps[-1][-1].components_.T
a = ax[1]
a.grid()
a.scatter(comps[:,0], comps[:,1], marker="^")
for col, comp in zip(x.columns, comps):
  a.text(comp[0], comp[1], col, color="green")
mx = max(abs(comps[:,0]))*1.1
a.set_xlim((-mx, mx))
mx = max(abs(comps[:,1]))*1.1
a.set_ylim((-mx, mx))
fig.tight_layout()
```
![Screenshot_2023-01-03_01-06-48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80588/abc1ff9e-4617-2f84-a488-3520d5e4b520.png)
![Screenshot_2023-01-03_01-07-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80588/e6403236-9116-7425-16f2-b0d0ea81d115.png)

左へ行くほど評価が高いので、第1主成分は、概ね評価（の正負を反転させたもの）に概ね対応しています。審査員側で見るとこの成分を特に強く反映しているのは（立川志らく、サンド富澤、ナイツ塙）の3名です。（中川家礼二、松本人志）も近い値です。（博多大吉、山田邦子）も正負では一致していますが、この軸をあまり重視していないようです。
第2成分では下側はどちらかというと正統派漫才っぽい芸風（さや香やオズワルド、カベポスター、男性ブランコ）、上側に変化球っぽい芸風（米田２０００、真空ジェシカなど）が配置しているように見えます。審査員側を見ると、（中川家礼二、松本人志、博多大吉）の３名は正統派を高く評価しています。全員関西ですね。一方、山田邦子は変化球のネタを評価する傾向が見えます。関東の審査員３名がこの軸では中程にいるところが面白い対比です。
得点の付け方が少し議論となったりしましたが、初見の印象と比べると良いバランスだったのかもしれません（ただし説明不能のノイズとなったものが残り20％の分散に残されているのかもしれません）。

## [おまけ] 順位点にした場合

```python
pd.DataFrame(x.rank().sum(axis=1).sort_values(ascending=False))
```
![Screenshot_2023-01-03_01-29-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80588/303d9b71-01c6-7d11-253d-19cb1f37db23.png)

現行の加算方式だと、見ていて審査員間の分散の違いが気になります。大体みんなが85〜100の範囲で点をつけている中で、一人が10~90 の幅で採点するとこの人が事実上の決定者になってしまうからです。
長所・短所はありますが、一つの代案は順位点方式（点数そのものではなく審査員ごとの順位を得点にする）にするということです。
ですが、今回に関しては順位点方式にしても上位3組の顔ぶれは変わらなかったようです。
リソースフォーク (._ で始まるファイル) をディレクトリから一括削除する方法

# リソースフォークとは？
Mac で USB メモリなどの外部ストレージを使用していると、`._` で始まるファイルがあちこちに勝手に作られてしまうことはありませんか？

これはリソースフォークと呼ばれる Classic Mac OS 特有のファイル構造を記録するために作られる隠しファイルです。Mac 本体のストレージでは通常このファイルは生成されませんが、USB メモリなどのファイルシステムが異なるストレージにデータを格納したり参照したりするとこのファイルが生成されることがあります。



# 問題点
USB メモリにデータを保管しているうちはそこまで気にならないのですが、USB メモリにあるデータを Mac 本体に移動させたりしたい場合に邪魔になることがあります。

USB メモリにあるディレクトリから Mac 本体の任意の場所に `mv` コマンドで移動させようとしたときに、一部のファイルでなぜか `No such file or directory` というエラーが発生することがあります。詳しい理由はわかりませんが、移動させる前はたしかに存在していたはずなのに、移動する過程でファイルの実態は消えてしまうがシステム側は存在していると認識してしまうのかもしれません。

`mv` コマンドの途中でエラーが発生すると、空ディレクトリがそのまま残ってしまったりするので、大量のディレクトリを USB メモリから Mac 本体に移動させたりしたい場合に空ディレクトリを削除する手間が発生します。なにより、単純に使われないファイルがいつまでも存在しているのは正直鬱陶しいです。

ディレクトリの中に大量にファイルがあると、それと同じ数だけファイルが生成されてしまうことがあるので、一つずつ削除するのは非常にめんどくさいです。



# 削除して大丈夫か？
これは昔の Mac のファイルシステムの名残で、今はほとんど使われていないため、削除しても全く問題ないらしいです。



# 削除方法
fd コマンドを使うと簡単に一括削除することができます。

念のため、削除されるファイル一覧を事前に確認しておきます。

```shell:Shell
cd /path/to/somewhere
fd -H "\._"
```

次にヒットしたそれぞれのファイルを削除します。

```shell:Shell
fd -H "\._" -x rm -f {}
```

論理的完全削除をしたい場合は `shred` コマンドを使います。

```shell:Shell
fd -H "\._" -x shred -fuvz {}
```

`fd` コマンドのオプションについては以下のとおりです。

* `-H`
    * 隠しファイルを表示するコマンドです
    * リソースフォークは `._` から始まる隠しファイルなので必須オプションです
    * `.` は任意の文字を表す正規表現の特殊文字なのでエスケープする必要があります
* `-x`
    * 別のコマンドを指定することで、ヒットした全ファイルに対してそのコマンドを実行します
    * `{}` には実行するたびに該当のファイル名が挿入されます

標準コマンド (`find` など) のみで一括削除する方法について何か良いやり方があれば教えていただけるとありがたいです 🙏



# 参考サイト
* [Finder上で「._」(ドット アンダーバー)から始まるリソースフォークを手軽に削除する](https://sites.google.com/site/bknobiboroku/mac/delete_resource_forks_from_finder)
チーム開発における”良いコード”とは

# まとめ

- この記事ではtoB SaaSのスタートアップで筆者がより良いコードベースを実現するために、実際に実践している内容を記載しています。
- プログラムを実装する際には、実装速度より、読みやすいコードを重視すべきであるという考え方と理由を記載しています。
- 混沌としてきてしまったコードベースから抜け出す最初のステップとして、「どのように書くか」「どこに書くか」を"チームで一致させる"ことから始めると良いという考え方と理由を記載しています。
- 実践内容の紹介と、それによって得た効果・問題点や感想を論じています。

# 本文
## 背景
MVP開発開始から2年余り、弊社SaaSプロダクト「Proceedクラウド」はこれまで機能拡張を積極的におこなってきた中で、コードベースはいわゆる「技術的負債」が溜まってきてしまっている状態です。状況を改善するために開発チームとして認識を合わせ、以下のような取り組みを実践しています。

## 実装の速さより読みやすさを重視する
特にアジャイルでのSaaS開発においては、ソースコードの大部分は何度も繰り返し読まれ、保守され、改修されていきます。たとえ実装に手間や時間がかかるとしても、ソースコードが読みやすくなる・保守改修しやすくなるなるのであれば、開発組織全体で見た総合的にかかる長期的なコスト（=その機能のために費やす時間）は短くなります。したがって東京ファクトリーでは、手早く機能を実装することよりも、時間がかかっても読みやすいコードを書くことに重きを置いています。

一般的に読みやすいコードを記述するためには、[リーダブルコード](https://www.oreilly.co.jp/books/9784873115658/)などの優れた書籍や、各言語のベストプラクティスなどを参考にするとよいでしょう。一方で全てのエンジニアあらゆる観点から常に読みやすいコードを書くのは、容易ではありませんし、開発する対象や開発手法・チームによって効果の出やすい点は変わってきます。

## 「どのように書くか」「どこに書くか」をチームで一致させる
「読みやすいコード」を書いたとしても他の人から人から見たら読みやすいコードではないかもしれません。たとえ読みやすい綺麗なコードを書く技術を究めたとしても、どのような視点で問題を捉えて分割していくかによって、読みやすいコードは変わってくるはずです。したがって継続的なチーム開発の中では、各々が綺麗なコードを書くスキルを身につけることに加えて、「チームの誰が書いても同じようなコードになる」ように仕組みを作っていくことが大切です。

また、読みやすいコードを実現するための観点として、大きく以下の2点が挙げられると考えています。

1. コードを読んで機能の内容がすぐにわかること
2. 各機能のコードがどこにあるかすぐにわかること

これらは、プログラムを実装するときの言葉に置き換えると、 1. はコードをどのように書くか、2. はコードをどこに書くかということに対応しています。これらをチームで一致させることて「（チームにとって）読みやすいコード」を実現させることができます。

## 実際の取り組み（命名規則とモジュール依存制約）
段階的に（かつ効果的に）読みやすいコードの実現を目指すために、変数名等の命名規則と、各モジュールの配置規則を作成しています。

コードをどのように書くかという観点では、まずは変数名や関数名が適切に名付けられることが大切であると考えています。「適切な名付け」には用語集や他のソースコードとの整合性も観点に含まれるため、適切に名付けられれば統一された実装になりやすくなります。命名規則を用意し、コードを読んで機能の内容がすぐにわかるように試みています。

コードをどこに書くかという観点では、アプリケーション全体としてはクリーンアーキテクチャベースでのレイヤ定義を行い、フロントエンドコンポーネントについては関心を持つモデル単位でのパッケージ切り分けを行なっています。例えば新しく機能追加するときには、どこにコードを追加すべきかをなるべく一意に特定できるように心がけています。また一部各モジュールから依存できるパッケージをLinterでルールとして設定し、規則に則らないコードを機械的に検知できる仕組みを試験的に導入しています。

## 効果と感想

上記の考え方を実践し、3ヶ月程度経過したころから全体的にポジティブな効果があったと感じています。改善前の定量的な指標が取れておらず比較はできていませんが、体感として、目的としていたオンボーディングやキャッチアップの高速化・コードレビューの時間の短縮・デグレの減少（レビュー段階で捕捉しやすくなった）が実現できたと強く感じています。コーディングルールを決めていくことで、実装にかかる時間が長くなる、といった問題なども今のところ(1年弱)感じていません。

副次的な効果として、コードレビューで指摘すべき範囲がレビュアー（筆者自身）の中で明確にできたことで、悩むことが減りました。コードレビューでは、レビュアーがこだわればいくらでも指摘点を挙げることができてしまう、といったことが一般に起こりがちだと思っています。そのためどこかで線引きを行う必要がありますが、これまでは変数名や関数名の適切さよりも個別のロジックが最適に組まれているかに（個人的な関心が強く）より目が向いてしまう傾向がありました。この記事にある考え方を社内に向けて整理・明文化する中で、細かいロジックの最適化よりも適切な変数名を与えることをより重視するようになり、コードレビューで指摘すべきこと・しなくて良いことが明確になってレビューが行いやすくなりました。

問題点として、いろいろな規則を文書化し共有してもなかなか実践・浸透させることが当初は困難であったことが挙げられます。それぞれの規則の背景や考え方を共有するために、理由などを説明した詳細なドキュメントを作成しましたが、あまり定着しませんでした。解決策として、背景などを省略し、要点のみを実例と共にチートシートとして１ページにまとめて共有したところ、だいぶ改善されたように感じました。より良いコード、というテーマは抽象的な議論になりがちなので、まず簡単に実践ができるようにして効果を体感しながら進めていくのが効果的で、その結果として背景なども体感しながら理解してもらいやすいのかもと感じました。（チートシートを作成する、という方法は、このトピックに限らず社内で非常に有効に機能しています。チートシートの作成やドキュメンテーションについての考え方については今後別途記事を作成し紹介します。）
MacでのRstudio上でのR versionの切り替え方法

WindowsOSのRStudioでは、[Tools] > [Global Options]よりRのバージョンが切り替えられる。Macでは、そのセレクトボタンが存在しない。

![screenshot 292.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88357/42f77ce9-a1b4-368d-939b-77342c371f77.png)

どうやってバージョンを切り替えるのかを記載する。

以下の環境で動作を確認できた。

- M1 chip
- macOS Monterey 12.5



# 全体の手順

- 複数versionのRのinstall
- RStudioのinstall
- RSwitchのinstall / 切り替え

# Rのinstall

以下のURLより複数バージョンinstallする必要がある。

https://cran.rstudio.com/

今回は、以下の2つのバージョンをWebブラウザよりinstallした。

- R-4.2.2-arm64.pkg
- R-3.6.3.nn.pkg

# RStudioのinstall

RStudioとしてmacOS 10.15+をinstallした。

https://posit.co/download/rstudio-desktop/

この時点でどのRのversionが利用されているかはRStudioを起動するとわかる。

![screenshot 294.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88357/482c9187-1512-06e9-ca98-341f91177dfa.png)

R3.6.3が実行されている。これは、私がR4系のあとに3系をinstallしたことに起因する。

```
ls -l /Library/Frameworks/R.framework/Versions/
```

![screenshot 293.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88357/fb71b037-36b1-ad81-384f-37047cc6ae2e.png)

3.６を差していることがわかる。

# RSwitchのinstall / 切り替え

RStudioからではなく、RSwitchというアプリを使ってversionを切り替える。

以下からinstallする。

https://rud.is/rswitch/

このアプリは起動しても何も起こらない。
macの画面上部に追加されており、それをクリックするとモーダルが出る。

![screenshot 303.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88357/1f1c0202-ecd8-05dc-03ad-54f0e637502a.png)
![screenshot 297.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88357/5282396f-4362-d704-f4fe-6de12d51273d.png)

4.2をクリックすると切り替えられる。
RStudioを再起動すると、Rのversionが4系になっていることがわかる。

![screenshot 295.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88357/f45da6c7-4628-5411-54bf-664b1f74d376.png)


# 参考

- https://rud.is/rswitch/
- https://btep.ccr.cancer.gov/docs/rtools/R%20and%20RStudio/2.6_switching_r_version/

- https://github.com/hrbrmstr/RSwitch アーカイブ済み
DHCPサーバの要件


DHCPサーバには以下の要件を満たすように設定を行います。
・アドレスの貸出（リース）期間はデフォルト30分、最大12時間とする
・サーバ、ネットワーク機器、プリンタは固定アドレス設定を行い、DHCPは使用しない
・DHCPサーバはドメイン名、デフォルトゲートウェイ、DNSサーバの設定値を配布する
・DNSサーバは全体で共通だが、ドメイン名は標準のものが設定されており、必要な場合、サブネットごとに設定を変更して配布する
・クライアントPCにはDHCPによる自動設定を行う
・メンテナンス作業用PCにはDHCPによる自動設定を行うが、アドレス以外は割り当てず、デフォルト値のみ使用する。また、アドレスの貸出期間は最大4時間とする。



DHCPはブロードキャストを使用して、その機能を実現させているため、DHCPサーバが別のネットワークにある場合、DHCPクライアントの要求は届きません。DHCPリレーエージェントは、別のネットワークに存在するDHCPサーバにDHCPクライアントからの要求を転送します。
ISC DHCPにおいて、DHCPリレーエージェントとして動作するのに必要なデーモンはdhcrelay。
40代が始めるWordPress副業 (1)

昨今の物価高、中国経済の停滞に伴う不況、増税により私の生活は厳しくなるばかり・・・
これはいよいよ副業でもせんとやってけん、ということで、最近副業が解禁された製造業の社内SEとして
サーバサイドや基幹システムばかりやっていた40代成りたてのおっさんが、
副業を始めて1年後までにどの程度稼げるようになるか、ツラツラと残していきます。

# やったこと

2023/1/1
Udemyで動画勉強中

ざっくり学ぶ、WordPress 6.xでノーコードサイト制作講座
　18/52まで
ちゃんと学ぶ、WordPress テーマ開発講座
　38/118まで

# 備忘録
ミドルウェア　WordPress
Query Monitor 開発補助
WP Multibyte Patch マルチバイト対応

サーバ　Local
Nginxは対応していないレンタルサーバ多いため、Apacheにしておく

開発環境　Visutal Studio Code
Japanese Language Pack 日本語化
PHP Intelephense PHP用フォーマッター Shift+Alt+F
　※WordPressのテンプレートタグをエラー扱いするので、[ユーザ設定]>[設定]から
　　Intelephenseの項目のUndefined Functionsをチェック外しておく

お作法
WordPress Codex
　テンプレート階層
　https://ja.wordpress.org/team/handbook/theme-development/basics/template-hierarchy/
　テンプレートタグ
　https://wpdocs.osdn.jp/%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%82%BF%E3%82%B0
M2 Mac/Anaconda Jupyter Notebook上でのTensorflowのインポートエラー対応法

# M2 Mac上のAnaconda環境でJupyter NotebookにTensorflowがimportできない問題。

まずAnacondaをアンインストール。そもそもErrorでアンインストールすら手こずった。

`conda update --force conda`
`conda install -c anaconda setuptools`
`conda install anaconda-clean`

上記でアンインストールはできた。再度M1用のAnacondaをインストールし直し、 (base)環境でTryするが結果は変わらず。

今のところ上手く行った方法は下記のみ
https://www.youtube.com/watch?v=5DgWvU0p2bk

 (tensorflow)という名称の環境を別途構築してJupyter Notebookを実行するという方法。毎回この環境の activateが必要になる。
下記で実行
`conda activate tensorflow`

でも毎回こんなことしないといけないのかな？忘れて (base) 環境でまたずっとエラー出て躓きそう。私のような初心者にはなかなか厳しいですね。
(OutSystems) Reactiveでのチーム開発で思うこと

OutSystemsは非常に生産性の良い統合開発環境である。
Eclipse&Javaで開発していた時の数倍以上の生産性が出る。
単独開発なら。

チーム開発になった途端に、以下が気になって仕方がなくなる。
・自担当分の変更が知らない間に他メンバの担当分に影響している
・自分の環境のみでデプロイ検証ができない(いきなり共有って感じ)なので
　思い切った変更がし難い
・マージサポートが弱いので、Conflictした際は大変気を遣う
・4人を超えてくるとPublishがぶつかりだす(ので、小刻みなPublishがし難くなる)

Traditional時代から今までModule分割と声掛け合いでなんとかなっていた面もあるが、
みんなリモートで声掛け合いは難しい状況になったし、そもそも人が増えると開発が
難しくなるというのは非常にもったいない。
最小のコミュニケーションで、各自が思い切った開発をできるようにならないと…

# というわけで
現在のプロジェクト(Reactive)では以下のような形を開発試行している。

それぞれの機能を別アプリとして切り出して疎連携
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563944/a9051a38-b775-02ce-bc48-9f79143bb6ab.png)

共有データはRESTでやり取りして、画面周りはもうお互い別アプリとして切り離し、
アプリごとに担当を決めて開発、iframeでガッチャンコしてしまうやり方である。
課題がないわけではない(iframe子画面から親画面のPopup操作が難しい等)が、今のところ
うまくいっているように感じる。

# そもそも
従来はモジュールを切り分ける(１アプリ内で開発パートを分ける)やり方だったが、次期構想である
ProjectNEOからはモジュールという概念がなくなるのである。モジュールで切り分けるのではなく
マイクロサービスとしてそれぞれの機能を独立して管理し、それを連携させてアプリにする構造だ。
それはつまり今回試しているような複数アプリで１画面を作る方針と合致している。

うん、なんかこのままで良いような気がしてきた。
2022年にpythonとAWS Lambdaで作ったもの

# 1. まえがき
去年作ったプログラムのまとめ記事となります。

# 2. 競馬関係のTwitter BOT
2022年の初めに、[「AWSではじめるインフラ構築入門」](https://amzn.asia/d/9bYYI0P)の本を購入し、アプリを作成
自分でも作成して見ようと、興味がある競馬関連のTwitterのBOTを4つ作成

・1号機（今日のハクサン地方競馬出走情報Bot）

https://twitter.com/hakusan_keiba/status/1608946512578609153?s=20&t=nBTTGQ4--CdqfEDeOkF1PA

・2号機（明日のメイショウ冠名馬中央競馬出走情報と今日の競走結果情報BOT）

https://twitter.com/MeishoBot/status/1608017675720228865?s=20&t=nBTTGQ4--CdqfEDeOkF1PA

- 3号機（マカオ競馬の日本人騎手レース結果Bot）

https://twitter.com/macau_keiba/status/1609469072277897217?s=20&t=nBTTGQ4--CdqfEDeOkF1PA

- 4号機（地方競馬所属騎手のJRA出走情報BOT）

https://twitter.com/NARjockey/status/1607648458420416519?s=20&t=nBTTGQ4--CdqfEDeOkF1PA

システム構成は、以下。
![システム構成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2780436/86cce6ff-d089-5ef6-c527-e18527e2f522.png)

## 2.1 苦労した点
- Twitter APIの申請と、認証キーの取得に試行錯誤
　また、Twitter API V2を利用しており、ネット検索してもV1の参考コードが多くヒットし、初Twitterするまで試行錯誤
- AWS Lambda の250MB容量制限に苦しみ、seleniumを使用したスクレイピングを諦め、beautifulsoupを使用
- エラー検知についても、色々な方法を試したが、結局、AWS SNS（Simple Notification Service）でのEメール通知に落ち着く

## 2.2 今後の改善点
- マカオ競馬の中野騎手が、2023年春にシンガポール競馬に移籍することから、シンガポール競馬の競走結果を取得処理を追加
- 勝利レースのツイートには、Youtubeのレース映像を追加ツイートするように、改修を行う予定
  トリガーについては、pubsubhubbubを利用し、Youtubeチャンネルの更新契機にAWS Lambdaが起動する構成を検討中
  「AWS Lambda Function URL」を利用すれば、「Amazon API Gateway」を使用せずともAWS Lambdaのみで実現可能そう

# 3. Google Analytics 4（GA4）のTwitter BOT
GA4のリアルタイムのアクティブユーザ数を取得し、閾値を超えた場合に、
TwitterするBOTを作成して欲しいという依頼を受けて以下のTwitter BOTを2022年末に作成

https://twitter.com/applihuguai/status/1609210298749308933?s=20&t=yt5DAbzqSokQOuRcrVEl1Q

ちなみに、2023年7月1日に、旧Googleアナリティクスは廃止され、GA4へ完全移行する

## 3.1 苦労した点
- 「Analytics Data API」を利用し、GA4のリアルタイム情報を取得しているのですが、あまりネット文献がなく試行錯誤
  そもそも新規APIのようで、やりたいことがまだ未実装だったりと、今後の機能追加に期待したい

## 3.2 今後の改善点
- 「Analytics Data API」のリアルタイム情報には、ページタイトルとスクリーン名の取得ができるが、
　該当ページのURL情報の取得ができない。
　※リアルタイム情報で無ければ、取得は可能・・・

# あとがき
最後まで読んで頂き、ありがとうございます。
ご紹介した競馬関係のTwitter BOTの2号機の作り方については、以下の書籍を作成しております。
興味があれば、こちらも参照下さい。

https://zenn.dev/motokoike/books/ef28866a3835cf
運用費用0円の個人開発方法

<h2>目的</h2>
Web開発をしたことがないエンジニア向けに、Web開発がとっつきやすくなる + 継続できるためのメモです。

Time to First Hello Worldという言葉があるくらい、開発を始めるとっつきやすさは大事です。それと同じくらい大事なことが、開発意欲の持続です。私の持論は、とりあえずWebサイトの「がわ」を公開してしまうことで、開発意欲の持続させられる。

お見苦しいですが、私の個人開発しているサイトが、以下になります。
https://www.aj-code.com

<h2>なぜ無料でできるのか</h2>
Azure Web Static Appを使うことで、月間100GBの通信容量まで無料で利用できる。

月間10万PVを目標にしても、1アクセス1MBまで利用できるので、十分でしょう。
ちなみに、100GBを動画再生に変換すると、約160時間相当なので、余裕な気がする。

おそらく、AWSなども無料枠があるが、今必要ないので、調べていない。

<h2>必要経費</h2>
Mustではないとはいえ、やっておかないとサイトとしてダサすぎるものが、以下になります。

<h3>カスタムドメインの取得費用</h3>
人気なドメインでない限り、<a href="https://www.onamae.com/">お名前.com</a>で無料で取得できるが、管理費として年間1000円程度は支払う必要がある。

<h2>モチベーションは、「フロントエンドの開発がしたい」</h2>
私は、Webの開発経験がないエンジニアで、まずはReactを使ってみたかった。なので、React x Azureで開発をしました。開発手順は、最低限のReactアプリを作成して、まずはデプロイ。デプロイが出来たら、少しずつ開発を進める方法を取りました。後は、git pushをするたびに、変更がインターネットに公開されるので、積み上げをしていくだけです。楽しいですよ。

<h3>React周り</h3>
<a href="https://learning.oreilly.com/videos/react-the/9781801812603/">O'ReillyのReactコース</a>

<a href="https://github.com/facebook/create-react-app">最小限のReactアプリの作り方</a>
<h3>Azure周り</h3>
<a href="https://learn.microsoft.com/ja-jp/azure/developer/javascript/how-to/with-web-app/static-web-app-with-swa-cli/introduction">AzureでWeb Static Appを作成する</a>

<a href="https://learn.microsoft.com/ja-jp/azure/developer/javascript/how-to/with-web-app/static-web-app-with-swa-cli/create-react-app">AzureでReactアプリをデプロイする</a>

<h2>次にやること</h2>
後は、自分のペースでReactを勉強しながら、サイトを作っていくだけですが、Webサイトを作る上で、以下のようなことをやらなければなりません。

<h3>1. ロゴ、Faviconの作成</h3>
嫌じゃなければ、Adobe Photoshopなどで作る。外注も面倒なので、作った方が早いと思う。

<h3>2. Font、画像素材を決める</h3>
自分の好きなフォントを決める。私は、Adobe Fontから選びました。

素材は、Adobe Stockを使いました。他にも無料のサイトがあるので、好きな素材を集めておきましょう。ちなみに、あなたがAdobeのものを使っていただいても、私には1円も入らないので、ご安心を。

- Adobe Font
https://fonts.adobe.com/

- Adobe Stock
https://stock.adobe.com/jp

<h3>3. カスタムドメインの購入</h3>
Azure Web Static AppのデフォルトのURLはあまりにもダサいです。こんな感じですので、やっぱりカスタムドメインを買いましょう。無料で買えるので、なんか得した気分になれますよ。運用費を払うときは、損をした気分にもなりますが。

<h3>4. DNSの設定</h3>
カスタムドメインを購入した場合、DNSの設定をなければなりません。お名前.comでもできるみたいですが、Azure DNS zoneを使うと、これも無料。期限なしです。
ここを見ながらやると、できます。

<a href="https://qiita.com/blackpeach7/items/23b49413cc8035192a6c">Qiita -【Azure×お名前.com】カスタムドメインを追加する</a>

<h3>5. サイトデザイン</h3>
面倒じゃなければ、Adobe XDなどを使って、まずはサイトの見た目を決めておくと、開発時にスムーズに実装ができる。私は面倒だったので、ノートにデザインを書いて、そのまま実装を始めました。分かってはいるけど、XDを習得する時間があるなら、Reactを書いたり、勉強したい気持ちが強くて、XDをやる気になれません。

<h3>6. Google Analytics</h3>
公開だけするより、アクセス解析をして、サイトを積み上げで良くしていきましょう。私もこれからやりますので、今は知見がありません。

<h3>7. 流入経路を考える</h3>
検索流入なのか、ブログ流入なのか、SNS流入なのか、複合的なのが良いに決まっているが、個人開発のサイト作った後に、やりたくなると思います。とは言っても、まずは作って公開しましょう。この辺を偉そうに考えだすより、開発したい意欲がある間に、サイトを作って公開することが第一優先だと思います。

<h3>8. マネタイズを考える</h3>
ここも同じです。ごちゃごちゃ考えずに、まずはサイトを作って公開する。そこまでいけば、開発モチベーションは保たれるし、マネタイズなんてそのうち考えればいい。一番やってはいけないのは、ローカルサイトだけ作って、開発意欲を満たしてしまうこと。何なら、ローカルサイトなんてものは、作り切る前に、みんな辞めてしまう。今あなたがWebサイトを公開したら、あなたは日本の9割のエンジニアより実績のあるエンジニアになれますから。まずは、公開しよう。

<h2>その他のリソース</h2>

- Twitter
https://twitter.com/GooglePython

- Note
https://note.com/banatie
Autowareの走行履歴を地図上にplotしてみる

# 概要と前提
「自動運転の走行履歴を地図上に描画できれば解析が楽なのでは???」
と思い、緯度経度日付の情報をもとにplotをしていく記事です。[autoware](https://github.com/autowarefoundation/autoware
)の環境構築や座標変換などのツールに関する説明は省かせてください。

緯度、経度、時刻の情報は用意されているものを使用しました。
```
35.61976132351556 139.77989858836102 2022-09-01 10:20:22.164477
.
.
35.62041580074247 139.77953530534174 2022-09-01 10:20:31.786464
35.621097767605946 139.77921576631155 2022-09-01 10:20:41.405413
35.62177083089212 139.7789073991445 2022-09-01 10:20:51.024529
35.622434542924566 139.77856604237553 2022-09-01 10:21:00.924588
```

# やってみたこと

## とりあえ地図を表示してみる
手始めにまずこの記事を参考にしながらpythonで地図を表示してみました。
https://qiita.com/Kumanuron-1910/items/12ce7aa02922927de2f4

コピペですが、すんなりと動いてくれました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639823/23a0ba0b-8ff2-0686-45de-87c64eecb98d.png)


foliumのピンは他にも色や形状などのオプションがあるようです。ピンにrosbag取得時の時刻情報なども載せたいですね。
https://chayarokurokuro.hatenablog.com/entry/2020/09/02/212350

zoom_startで地図の倍率を変えられるみたいですね。
ピンはデフォルトのものがシンプルで見やすい気がするのでデフォルトのピンを使用しようと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639823/ee71e9cc-786f-da20-6946-abea0f0da035.png)

## 実際の地図でもう少し具体的な検討をしてみる
日本縦断みたいなことをしない限り広域の地図はいらないので、zoom_startの倍率は15~20くらいに設定していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639823/d7801167-47a5-db6b-6510-c6651df6be18.png)

markerも複数したのが反映されてそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639823/848bd59e-759f-4e7a-f012-fcf6bdbe742f.png)

とりあえず地図の中心はplotしたい緯度経度付近であってほしいので最初の緯度経度の値を中心に地図を描画することにしました。描画の中心をx,yの平均値にするなど工夫するのもありだと思います。


# 検証

## とりあえずplotしてみる
お台場で走行したときのrosbagの位置情報がきれいにplotされました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639823/586edfc6-775e-5343-c54b-b9fb37967e18.png)

ちょっとアイコンが密なので、アイコンの間隔を50m間隔くらいに間引いてようと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639823/3985f845-b251-0c94-fb7d-870cc7825bf6.png)

ちょっと過疎になりすぎたので、アイコンを間引く間隔は20m間隔くらいにしてみようと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639823/9984dac0-3d9b-9360-8623-397f48a24588.png)

google mapでの測量だと360mなのでだいたいマーカー19~20個分くらい。plot上だと19個なのでだいたい距離はあってそうですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639823/1c78990d-cfc4-788f-fd85-e3eb76f58823.png)

## 完成形

時刻情報をpopupとして追加し、選択したときに表示するような仕組みにしてみようと思います。
`folium.Marker(location=[lat, lon],popup=date_time).add_to(map)`
のような形でかんたんに追加できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639823/6bf34dba-a168-f72a-7c85-7fc1c0e8df01.png)

# 補足
実際はbagfileから情報を取得し、座標変換し描画していますが、今回は簡単のために地図に描画の部分だけ書いてみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639823/1e9c8b51-b926-61b4-772b-143a425f11fd.png)
SAMで環境別にデプロイ

## やりたいこと
samで構築されるリソースを各環境(dev/prod)ごとに分けたい。

## 環境別に分ける方法
- samconfig.tomlを環境別に分けて記述する。
- template.yamlにパラメータとして環境情報を渡して、環境別に各リソース名を切り替える

## 構築するリソース
- S3
- Lambda
- DynamoDB

## template.yaml
Parametersで外部から環境情報を渡せるようにし、各リソース名を環境ごとに切り替える。
※関連個所のみ記載
```
Parameters:
  Env:
    Type: String
    AllowedValues:
      - dev
      - prod

Resources:
  CreateThumbnailBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub create-thumbnail-test-${Env}
  CreateThumbnailFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: create_thumbnail/
      Handler: app.lambda_handler
      Runtime: python3.9
      FunctionName: !Sub create-thumbnail-${Env}
      Architectures:
        - x86_64
      Environment: 
        Variables:
          ENV: !Ref Env
      Policies: 
        - DynamoDBCrudPolicy:
            TableName: !Ref CreateThumbnailTable
      Events:
        S3Input:
          Type: S3
          Properties:
            Bucket: !Ref CreateThumbnailBucket
            Events: s3:ObjectCreated:*
            Filter:
              S3Key:
                Rules:
                  - Name: prefix
                    Value: input/
  CreateThumbnailTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: !Sub create-thumbnail-${Env}
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions: 
        - AttributeName: id
          AttributeType: S
      KeySchema: 
        - AttributeName: id
          KeyType: HASH
```
環境変数を使用することで、Lambda処理内で環境の判別が可能となる。
```
      Environment: 
        Variables:
          ENV: !Ref Env
```
Lambda(Python)では設定した環境変数を以下で取得できる。
```
os.environ['ENV']
```
## samconfig.toml
環境ごとにデプロイ情報を記述。
parameter_overridesの設定値が、template.yamlのParametersに渡される。
```
version = 0.1
[dev]
[dev.deploy]
[dev.deploy.parameters]
stack_name = "sam-app-dev"
s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-xxxxxx"
s3_prefix = "sam-app-dev"
region = "ap-northeast-1"
confirm_changeset = true
capabilities = "CAPABILITY_IAM"
image_repositories = []
parameter_overrides = [
  "Env=dev"
]

[prod]
[prod.deploy]
[prod.deploy.parameters]
stack_name = "sam-app-prod"
s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-xxxxxx"
s3_prefix = "sam-app-prod"
region = "ap-northeast-1"
confirm_changeset = true
capabilities = "CAPABILITY_IAM"
image_repositories = []
parameter_overrides = [
  "Env=prod"
]
```

## デプロイ方法
dev
```
sam deploy --config-env dev
```
prod
```
sam deploy --config-env prod
```

## ローカル実行時に環境変数を設定
環境変数ファイルを作成
```
{
  "CreateThumbnailFunction" :{
    "ENV": "dev"
  }
}
```
作成したファイルを--env-varsで指定して実行
```
sam local invoke --config-env dev
```
KMMでvalue class foo(val bar: String)を使うとObjective-Cでid型と認識され、SwiftではAnyになる（未解決）

# この記事は

最近KMM周りの記事を書いている @uehatsu です。この記事はそんな連投記事の１つになります。発生している症状はタイトル通り(SSIA)なんですが、それだけでは味気ないのでちょっと自分の踏んだ地雷を解説してみたいとおもいます。ちなみに未解決です。

https://qiita.com/uehatsu/items/57a8aa86ed544f8c2627

https://qiita.com/uehatsu/items/bce9789ae483c4287d26

# ことの発端

[Movable Type Advent Calendar 2022](https://adventar.org/calendars/7425)の[記事](https://qiita.com/uehatsu/items/f9d8c985e11526613ed8)を書いた時に「ボツになった記事がある」と書きました。その没記事を成仏させるためにKMMでMovable Type DataAPI SDKの制作に勤しんでいました。

https://qiita.com/uehatsu/items/f9d8c985e11526613ed8

その中で、どうせ記事を作るならValue Objectを使ってEntityを表現したいと、Kotlinの言語仕様にある`value class（旧inline class）`を用いてValue Objectを表現したいなとKMMのCommon実装の中で利用していました。一通りMovable Typeのバージョンオブジェクトの実装が終わった時に、iOSのプロジェクト側で挙動を試したところ、Floatをプロパティにもつvalue classは正しくfloatとしてSwift側で認識されているのに対し、Stringをプロパティに持つvalue classはAnyとして認識されていました。最初は全てのvalue classがAnyとして認識されているのかと思ったのですが、実際はStringだけ。おかしいと思って、いくつかTwitterに投稿しています。

https://twitter.com/uehatsu/status/1609903015963807744

https://twitter.com/uehatsu/status/1609903956007989251

https://twitter.com/uehatsu/status/1609919490103578627

最終的にKotlinのバージョンを1.7.21から1.8.0に上げてみましたが、状況は変わらず、、、

https://twitter.com/uehatsu/status/1609922135400808448

この一連のTweetの最中にビルドされたヘッダーを見て、Objective-Cでは`id`として認識されていることがわかりました。以下のヘッダーの`endpointVersion`が`id`として認識され、`apiVersion`は`float`として認識されていることがわかります。

```obj-c:shared.h
/**
 * @note annotations
 *   kotlinx.serialization.Serializable
*/
__attribute__((objc_subclassing_restricted))
__attribute__((swift_name("MTVersion")))
@interface SharedMTVersion : SharedBase
- (instancetype)initWithEndpointVersion:(id)endpointVersion apiVersion:(float)apiVersion __attribute__((swift_name("init(endpointVersion:apiVersion:)"))) __attribute__((objc_designated_initializer));
@property (class, readonly, getter=companion) SharedMTVersionCompanion *companion __attribute__((swift_name("companion")));
- (SharedMTVersion *)doCopyEndpointVersion:(id)endpointVersion apiVersion:(float)apiVersion __attribute__((swift_name("doCopy(endpointVersion:apiVersion:)")));
- (BOOL)isEqual:(id _Nullable)other __attribute__((swift_name("isEqual(_:)")));
- (NSUInteger)hash __attribute__((swift_name("hash()")));
- (NSString *)description __attribute__((swift_name("description()")));
@property (readonly) float apiVersion __attribute__((swift_name("apiVersion")));
@property (readonly) id endpointVersion __attribute__((swift_name("endpointVersion")));
@end
```

ここで、以下のYouTrackを見つけます。2019年から大きなアップデートはなく。他のissueやYouTrackにも派生していますが議論が活発とは言えません。

https://youtrack.jetbrains.com/issue/KT-32352

ヘッダーファイルを眺めると、Stringクラス以外は変換のための記述があるので、KotlinのStringクラスの持ち方に原因がありそうだなという所までは想像がつきました。ひょっとするとObjectをプロパティに持つvalue classは同じ挙動になるかもしれません（そこまでは未調査）。

# 自分なりの結論

__KMMではvalue classはまだ使えない orz__

どなたか解決方法をご存知の方いたらコメントください😭
API Gateway経由でLambdaを呼び出す

## 概要
API Gatewayを自身で構築したことがなかったので、簡単なものを構築してみた。
/test(GET)でLambdaを呼び出せるようにする。

## 手順
1. Lambda関数を作成
2. API GatewayでREST APIを作成
3. APIをデプロイする
4. APIにアクセス

## Lambda関数を作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255243/22611345-9295-9f9e-80ec-393dec386d6b.png)
コードは初期のまま
```
export const handler = async(event) => {
    // TODO implement
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    };
    return response;
};
```

## API GatewayでREST APIを作成
### REST APIを作成
![create-restapi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255243/8adb0944-8b7e-16e3-f49b-baaf01caf166.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255243/ef246a55-90f7-ce96-9b95-9f06921a3122.png)
### リソースを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255243/8b44b0f9-1fbc-ecee-02df-a70eb1d2f2a8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255243/2434fa6e-5244-b11f-73b8-3789a39ab73a.png)
### メソッドの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255243/c2364767-7b71-7714-6209-60cad899fd63.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255243/62a8e6a3-8a17-96cc-d90d-eee55046025d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255243/0f1661e7-97a0-38b5-c944-7759f50f17c0.png)

## APIをデプロイ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255243/c086f043-003e-6fd1-3acd-723c21a73a65.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255243/d1041cf4-44e0-f2f2-46ac-29a0f86132eb.png)

## APIにアクセス
```
curl https://xxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prod/test
>> "Hello from Lambda!"
```