OmniAICreator/Qiita-1.07M huggingface dataset:
Advent Calendar 2022 HERE開発者向け情報まとめ

To develop the best maps and location experiences for people and businesses to navigate their world!

https://www.here.com/jp/learn/blog/qiita-advent-calendar-2022-here

HERE Advent Calendar 2022　:santa_tone2:　に参加される予定で、初めてHEREを触られる開発者、技術者の皆さんにご活用いただけると思われる情報をまとめてみました。皆様のお役に立てば幸いです！

# HEREについて
HERE https://www.here.com/ のルーツは、小さなチームがアメリカ西海岸ベイエリアでデジタル地図データベースの開発をスタートしたNAVTEQです。
1985年の創業以来35年以上、世界中の企業やデベロッパーと最高の地図と位置情報関連技術の開発に取り組んでます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2725955/d3eb8c0a-cd07-4fda-11c8-fa457d0398ff.png)

HEREの位置情報技術は、幅広い用途で多くのアプリケーションに活用されています。世界中約200万人の開発者がHEREプラットフォームに直接アクセスもしくは、AWS、Microsoft Azure、Salesforce の MuleSoftなどのデベロッパーエコシステムを経由して HEREプラットフォームの機能を活用いただいています。

まだ、
HEREプラットフォームのアカウントをお持ちではない方は、下記投稿をご覧いただきアクセスください。

https://qiita.com/kekomat/items/d2e29bac84a27c1ec521


# 開発者向けドキュメント
https://developer.here.com/documentation

英語での情報提供が中心となるのですが、開発者向けドキュメントURL冒頭にjpを追加し
https://jp.developer.here.com/documentation
とすると一部、日本語機械翻訳が提供されているページもございますので、ご活用ください。（微妙な機械翻訳がございましたら、コッソリご連絡いただければ幸いです。。。:sweat:）

合わせて、
- Understand basic map concepts　https://developer.here.com/documentation/mapping-concepts
HEREに限らず地図業界でよく使う用語集など便利です。
また、
- Explore examples　https://developer.here.com/examples
- Tutorials　https://developer.here.com/tutorials
各サービスのサンプルやチュートリアル下記リンクがまとまっていますので、一度ご覧いただきご活用アイディア創出にご活用ください。

## HERE location services 
HERE プラットフォームを初めてご利用開始いただくにあたって、インフラストラクチャやアルゴリズムを意識はせず活用いただける下記図　HERE プロダクトポートフォリオとテクノロジースタック　の中段にあたる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2725955/bc66cd90-b62a-1f2a-aeb6-b67555e24981.png)

REST API ロケーション サービス　https://developer.here.com/develop/rest-apis
の、地図表示、ルーティングあたりからお試しいただくのが良いのではないかと思ってます。

https://developer.here.com/develop/rest-apis

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2725955/fffb2eac-806f-aaef-3a00-5ecfeb032e8c.png)

その際の認証周りやユーザー、コスト管理について、
- Identity & Access Management Guide　https://developer.here.com/documentation/identity-access-management/dev_guide/index.html

https://developer.here.com/documentation/identity-access-management/dev_guide/index.html

を、あわせてご覧ください。



# まとめ

この情報が皆様のお役に立てば幸いです。HERE公式 Developer blog　https://www.here.com/learn/blog?type=developer にも、記事を書き始めておりますので、そちらの最新情報もご覧いただけますと幸いです。
HEREプラットフォームを使用したアプリケーションが日本で構築され、世界に展開されていくことを見るのを楽しみにしています! :japan::santa:

### その他リソースリンク

- HERE Developer blog　https://www.here.com/learn/blog?type=developer
- Domain names for HERE services　https://developer.here.com/documentation/identity-access-management/dev_guide/topics/hosts-mapping.html
- Product Lifecycle　https://developer.here.com/documentation/product-lifecycle-policy/customer_notice/index.html
- Learn about pricing　https://developer.here.com/pricing
- Support Service https://www.here.com/pricing/support-plans
4. random rotation decision tree, simulated annealing decision tree

# random rotation decision tree, simulated annealing decision tree
　今回はOblique DTの派生である、random rotation decision treeとsimulated annealing decision treeを紹介します。今回は非常に短いです。

# random rotation decision tree
　これまた非常に簡単で、通常のDTへの入力をそのまま使うのではなく、Random Rotationを施してから分割するだけです。完

## random rotation matrix
　これだけで終わるのももったいないので、random rotation matrix の生成について解説します。参考にした論文は下記のものです。
http://article.sapub.org/10.5923.j.ajcam.20170702.04.html
　アルゴリズムは非常に簡単なもので、
1. N次元のそれぞれ異なるランダムベクトルを2つ、XとYを作成する
1. それぞれのベクトルをいずれかの軸（論文中では第１軸）に平行に変換する行列、MxとMyを求める
1. Myの逆行列とMxをかけたものを求める
以上です。

### 2次元の場合
　解説が必要なのは上記の２の部分のみのため、こちらの詳細を解説します。最も簡単な２次元のベクトルを考えます。
```math
X = 
\begin{pmatrix}
a  \\
b  \\
\end{pmatrix}, 
Y = 
\begin{pmatrix}
c  \\
d  \\
\end{pmatrix}, 

```
このベクトルを以下のように変換する変換行列$M_X, M_Y$を定義します。
```math
\widetilde{X} = 
\begin{pmatrix}
\sqrt{a^2+b^2}  \\
0  \\
\end{pmatrix}
= M_X
\begin{pmatrix}
a  \\
b  \\
\end{pmatrix} \rm{with} ~~
M_X = 
\begin{pmatrix}
c_\theta & -s_\theta  \\
s_\theta & c_\theta  \\
\end{pmatrix}, ~~~
c_\theta = a / \sqrt{a^2+b^2}
\\

\widetilde{Y} = 
\begin{pmatrix}
\sqrt{c^2+d^2}  \\
0  \\
\end{pmatrix}
= M_Y
\begin{pmatrix}
c  \\
d  \\
\end{pmatrix} \rm{with} ~~
M_Y = 
\begin{pmatrix}
c_\phi & -s_\phi \\
s_\phi & c_\phi  \\
\end{pmatrix}, ~~~
c_\phi= c / \sqrt{c^2+d^2}
```

最終的に生成されるRandom Rotation Matrixは、以下で定義されます。
```math
M = M_X^T M_Y
```

念のため、scipy.stats.special_ortho_group と、上記の計算方法で計算したものから計算された角度を比較してみます
（変換行列の(0,0)成分を$\arccos$で変換し、角度を求めました）。一様に分布していることがわかると思います。

![scipy_random_rotation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323271/b9bdd0f2-38a6-ee81-aaaa-0f139f77ac33.png)　![scratch_random_rotation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323271/8ced8a71-2c33-6410-9702-3ecc1dad9519.png)

### 3次元以上の場合
　基本的には３次元以上の場合においても手順は同様です。論文中では並列実行性にも言及していたため、簡単に触れておきます。

　最も単純には、N次元目とN-1次元目の間で処理を行い、次にN-1次元目とN-2次元目の間で処理を、という風に続きます。
並列実行は、例えば８次元のベクトルの場合には、
1. 1次元目と2次元目, 3次元目と4次元目, 5次元目と6次元目, 7次元目と8次元目ごとに変換を行う
1. 1次元目と3次元目, 5次元目と7次元目ごとに変換を行う
1. 1次元目と5次元目で変換を行う
という風に進められます。段階の処理は完全に並列に進められるため、並列実行ができるという具合です。
ただ、論文中には実際の処理時間などについての記載はありませんでした。私も実装してみましたが、特にうまくいきませんでした。


# simulated annealing decision tree（SADT）
　その名の通り、分割条件を決める際にsimulated annealing つまり焼きなまし法を用いるものです。こちらは広く一般的に知られているものかと思いますので、詳細な解説は割愛いたします。係数と切片をランダムに変化させ、既定の温度やIteration数などに達した場合に処理を停止します。

　文献を読んでいて面白いと思った点は、確か1997年ごろのものでRandom Forestが発表される前でした。文献中には単純にDecisionTreeを構築しても、ほぼ同じものしかできないため、アンサンブルの意味がないというような趣旨の記載がありました。今であればBagging、RandomSubsapceなどは簡単に思いつくものです。また、Oblique Splitなので当たりまえかもしれませんが、複数のSADTをいくつも作成し、最も小さい＝ノードの数が少ないSADTが最も精度が良かったという風な記載もあったと思います。どの文献か忘れてしまったため、現在捜索中です。
scikit-learnで学習した分類モデルをM5Stackにデプロイする方法

# はじめに
初めてのQiita投稿になります。
今後、業務で学んだこと、躓いたことを継続的にアウトプットしていければと考えています。

# 事前準備
### 環境
```
Python 3.9.7
Arduino IDE 1.8.19
M5Stack
```
### 必要なライブラリを事前にインストール
```console
pip install scikit-learn
pip install micromlgen
```

# 分類モデルを作成する
分類モデルを作成するために、データセットを準備します。
今回、サンプルデータセットで有名なirisデータセットを採用しました。
``` python
# データセットの読込
from sklearn.datasets import load_iris
data = load_iris()
# 特徴量データセット
X = iris.data
# ラベルデータセット
y = iris.target
```
次に、用意したデータセットを用いて分類モデルを作成します。
今回は、ランダムフォレストを採用しました。
```python
# ランダムフォレストを用いて分類モデルを作成
from sklearn.ensemble import RandomForestClassifier
clf = RandomForestClassifier(random_state=1)
model = clf.fit(X, y)
```
# 学習したモデルをC言語で出力する
上記で学習したモデルをC言語で出力します。
```python
from micromlgen import port
classmap = { 0: 'setosa', 1: 'versicolor', 2: 'virginica' }
# port()の第一引数に学習したモデルを指定
# port()の第二引数にクラスマップを指定（省略可能）
# クラスマップを指定すると、ラベル予測時に各ラベルに割り当てられた文字列を出力させることが可能。
c_code = port(model, classmap=classmap)
# C言語で書かれたコードを出力
print(c_code)
```
ちなみに`micromlgen`がサポートしているモデルは下記となります（https://github.com/eloquentarduino/micromlgen より引用）。
> micromlgen can port to plain C many types of classifiers:
・DecisionTree
・RandomForest
・XGBoost
・GaussianNB
・Support Vector Machines (SVC and OneClassSVM)
・Relevant Vector Machines (from skbayes.rvm_ard_models package)
・SEFR
・PCA

# 分類モデルをM5Stackにデプロイする
Arduino IDEで、新しいスケッチを開きます（既存のスケッチでも可）。
### model.h作成
空ファイル`model.h`を作成して、[「学習したモデルをC言語で出力する」](#学習したモデルをc言語で出力する)で出力したコードの中身をコピペします。
![スクリーンショット 2022-11-30 21.40.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930944/04e386ee-52fb-ed0f-7d7d-29a2a76124b5.png)
### inoファイル編集 ＆ M5Stackにデプロイ
続いて、inoファイルに下記コードを記述し、M5Stackに書き込みを行います。
setosaの特徴量をサンプルとして用意し、C言語で出力された学習モデルがラベルを予測できるかM5Stack上で確認します。

```c
#include <M5Stack.h>
// 分類モデルを変換させたコード
#include "model.h"
// ランダムフォレスト以外の分類モデルを使用する場合、model.hの中身によってクラス名を変更
Eloquent::ML::Port::RandomForest classifier;

void setup() {
  M5.begin();
  M5.Power.begin();
  // ラベル予測用のサンプル（0: setosa）
  float X_sample[] = {5.1, 3.5, 1.4, 0.2};
  // ラベル予測結果出力
  Serial.print("Predicted class: ");
  Serial.println(classifier.predictLabel(X_sample));
}
```
M5Stackに書き込み後、シリアルモニタを確認するとsetosaが出力されていることを確認できます。
以上、scikit-learnで学習した分類モデルをM5Stackにデプロイする方法となります。
![スクリーンショット 2022-11-30 0.38.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930944/a9c0c05a-ffae-66f3-10c0-57d4a3e337e8.png)

# さいごに

間違い等あればご指摘いただけると幸いです。

# 参考文献

https://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_iris.html

https://eloquentarduino.github.io/2019/11/how-to-train-a-classifier-in-scikit-learn/

https://github.com/eloquentarduino/micromlgen
1. FortLearnerについて

# FortLearnerについて
　FortLearnerはFortranでMachine Learningのアルゴリズムを（簡単だとおもったものから）実装しているライブラリです。PythonにはScikit-Learnがあるように、ほかの言語でもそれに相当するライブラリがすぐに見つかるかと思います。Fortranにはそれに類するものが見つからないので、作ってみようと思い立ちました。というのは後付けで、最初は新卒で就職してからあまりにも勉強していないことに（帰宅してからも気力が尽きていたこともありますが）愕然としたからです。とはいえ、完全に仕事に関係していないことを勉強するのはモチベーションがわかないと思い、機械学習の実装をすれば仕事でScikit-Learnを使うときに挙動がわかったり、お客様に説明するのもやりやすいかと思ったからです。

# アルゴリズムの選択
　これは上記の通り簡単だと思ったものからやっています。また、なるべく網羅的にやりたいと今は思っているので、基本的なアルゴリズムともう１，２個実装をすませたら次の種類のものという感じに選んでいます。

# 実装方針
　とりあえず速ければいい、でもせめて自分が拡張するときにあんまりやりづらくないように、という程度の方針でやっています。なので、可読性、保守性という観点はほぼありません。速度の基準は何度も出してしまいますが、Scikit-Learnです。統一されたインターフェースを維持しつつ、圧倒的多数のアルゴリズムを実装しているので、せめて速度くらいは勝ってみたいという気持ちです。正直このような公式ライブラリは絶対に勝てないだろうなくらいに思っていたのですが、いろいろ捨ててしまえば（捨てるといろいろダメな気がしますが）速度くらいは勝てるんだなというのはすごくうれしかったです。

# 実装済みアルゴリズム
　実装済みアルゴリズムは以下です（アルファベット順）。記事にはしていますが、実装できていなアルゴリズムもいくつかあります（間に合わなかったともいいます）。DecisionTree系が妙に多いのは最初に実装したものがDecisionTreeであったことと、最初に考えていたライブラリの名前が関係しています。レポジトリにはファイルだけあって、まったく実装されていないものが残っています...
* boosting_trees
    * adaboost
    * gradient_boosting_with_clouds
    * gradient_boosting_with_extra_tree
    * gradient_boosting_with_lawu
    * gradient_boosting_with_decision_tree
* clustering
    * breathing_kmeans
    * dbscan
    * kmeans
    * minibatch_kmeans
* decision_tree
    * clouds
    * decision_tree
    * extra_tree
    * isolation_tree
    * lawu
    * oblivious_tree
    * random_rotation_tree
    * sadt
    * sliq
* decomposition
    * nipals
    * pca
* forest
    * deep_forest
    * extra_trees
    * isolation_forest
    * random_forest
* linear_regression
    * linear_regression(lasso, ridge)
* logistic_regression
    * logistic_regression
* multi_layer_perceptron
    * multi_layer_perceptron
* nearest_neighbor
    * balltree
    * brute_force
    * kdtree
    * lsh
    * product_quantization
* sgd_estimator
    * sgd_estimator

# 記事内で書くこと
　アルゴリズムの簡単な解説をします（思った以上に時間がかかってしまいました。できればpythonで実装したものも入れたかったのですが）。また、実装していて困ったところや工夫した点などを書きたいと思います。

以上
modernization とは

## 勉強前イメージ

そもそも英語の意味がわかってない・・・

## 調査

### modernization とは

モダナイゼーション と読み、意味としては古なったIT資産(ハードウェアやソフトウェア)を新しいものに置き換えることを指します。
modernizationの元々の意味は近代化などの意味になります。

### モダナイゼーションを行う方法

- リホスト

サーバなどの基盤を新しく作り、アプリケーションなどのデータはそのまま使用することを指します。
素早く移行できる点がメリットになります。

- リライト

既存の資産を活かしながらアプリケーションのソフトウェアのコードを新しい言語に書き換えて使用する方法です。
より適切な言語を使用することで使いやすくセキュリティ性などの面で向上をはかることができます。

- リプレイス

機器やシステムを新しいものへ刷新する方法
業務改善を行った上で昔のシステムを受け継ぐことなくシステムを再構築します。

## 勉強後イメージ

パッと見たときに
モダナイゼーション = リプレイスじゃない？っておもったけど
アプリケーションに焦点を置くのか、HWに焦点を置くのか、どっちもなのか。ってことですね。

## 参考

- [モダナイゼーションとは？基本情報から具体的なメリットまで詳しく紹介](https://hnavi.co.jp/knowledge/blog/modernization/)
- [モダナイゼーションとは？ レガシーシステムからの脱却](https://www.hitachi-solutions-create.co.jp/column/core-system/modernization.html)
じつはいろいろあるobniz APIのお話


これは[obnizアドベントカレンダー2022](https://qiita.com/advent-calendar/2022/obniz)の1日目の記事です

obniz使ってるよ！　ってひとでも案外obnizが提供しているいろいろなAPIについては知られてなかったりするので、ちょっとAPIについて書いてみます



## obniz ハードウェアAPI (Websokcet)

一番みんなが使ってるAPI。 obniz.jsが裏で使っているもの。
Websocketを利用して双方向通信をしながらデバイスの制御を行います。
https://obniz.com/ja/doc/reference/cloud/hardware-api/websocket-api


#### できること
- IOのON/OFFやUARTの送受信など、ピンの制御
- ディスプレイやスイッチなど、obnizBoardについているコンポーネントの状態把握


基本的にはデバイスに関することができます。Websocketなので双方向通信ができるのがポイントで、
IOの状態を変更するといったプログラム→デバイスの通信も、IOの状態を取得するといったデバイス→プログラムの通信も可能です。

![obniz api.drawio (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227015/d066e426-6206-4521-2520-35f3b4905777.png)




WebsocketでAPIを作って公開しているところ、obniz以外だと全く知らない。。。
ブロードキャストで配信だけならビットコイン取引所とかあるんですが、個別のAPIは見ないですね。

websocketの中身はJSONになっていて、そこも含めて全部公開しています。
https://obniz.com/ja/doc/reference/websocket/ws


## obniz ハードウェアAPI (REST API)

obniz ハードウェアAPI (Websokcet)って一般的じゃないよねってことで一応用意したREST API。
RESTは双方向通信ではないため、IOの状態を変更するといったプログラム→デバイスの通信はできるが、状態の確認などのデータ取得はできない。

https://obniz.com/ja/doc/reference/cloud/hardware-api/rest-api

#### できること
- IOの状態を変更する、UARTを送信するなどの1方向通信

![obniz api.drawio (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227015/c4d74d60-8589-375d-ad7d-eca7231e8758.png)


REST APIとしてつくったものの、あまり使われてない。（みんなobnizjsを使ってくれている）

## obniz Messaging API

obnizjsの中にひっそりと含まれているjs同士が通信するためのAPI.
obnizjsの中にあるのに、デバイスには通信が届かず、代わりにそのデバイスにつながっているobnizjsに通信が届く。

なお、じつはREST APIからこのmessageを送ることもできる

https://obniz.com/ja/doc/reference/common/messaging

#### できること
- 複数のobnizjs同士で文字列を送りあえる


![obniz api.drawio (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227015/31a6d91d-07d4-2e1b-97b6-565189353849.png)


複数のobnizjsから１デバイスを制御する際の連携機能として作成。うまく使えば複数人が１つのデバイスを協調して動かすみたいなことができるかも。
※obnizの作品じゃないけど、 [論理演算式コントローラー](https://protopedia.net/prototype/3388) みたいなのって面白いなぁとおもってます



## アプリのクラウド実行
API・・・と見せかけてAPIじゃないやつ
ただ、使い方によっては独自APIを生やしている、と言えなくもない。いや、言えないか。

予めobnizが動くHTMLを作っておき、それをwebhookで起動する方法。webhook起動なので、いろいろなサービスと連携することができる。


https://obniz.com/ja/doc/reference/cloud/app/browserapp-cloudexec

#### できること
- 30秒以内でobnizデバイスを制御できる
    - デバイスの制御はobnizjsでできることなら何でも
    - というかHTMLでできることなら何でも


![obniz api.drawio (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227015/da33feae-8162-9543-e3c8-3883d40065c0.png)




## obniz Cloud API


知る人ぞ知る、開発者コンソール内をブラウザを使わずに操作できるAPI。
デバイス一覧とか、アプリのインストールとかそういう普通は人がやるような作業を自動化するためのAPI
UIをポチポチ操作する代わりになる


https://obniz.com/ja/doc/reference/cloud/cloudapi


#### できること

- 開発者コンソール内で行っていたことを自動化できる
- デバイス一覧取得
- アプリのインストール
- デバイス設定の変更　など



![obniz api.drawio (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227015/744dfee5-fcb1-3240-d87c-24ff0fcfff7b.png)
※画像はイメージです



少量のデバイスだったらUIでやったほうが早いけど、大量のデバイスを持っている場合にありがたいやつ。
GraphQLで提供しているので、お好きなクライアントライブラリを使って利用することができる。



---

というわけで、obnizが提供しているAPIを紹介してみました！
大抵の人は最初の obniz ハードウェアAPI (Websokcet)しか使ったことないんじゃないかなと思います。

是非機会があれば使ってみてください。


あしたは @wakasamasao さんです！
タイトルみたら アプリのクラウド実行 について詳しく書いてくれそう・・！（期待）
GASでスプレッドシートに書き込んだイベントをカレンダーに追加するコードを書いた話

# 概要
Googleカレンダーに同じ名前のイベントを説明欄の内容を変えて作成したいと思ったから、スプレッドシートに日付と説明を入力し、横のUpdateボタンを押すと指定した日付にイベントが作成されるコードを書いた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734184/01ea209e-439f-2ce3-e455-c60bafeb24ec.png)


おまけとしてイベントに割り振られる色を`ORANGE`と指定してある
また、日付と説明を入力し、GoogleAppsScriptによってカレンダーにイベントとして追加された行について、イベントが追加済みであることを明示する列(Added列)を用意した

# 実装の流れ
以下、実装の流れを軽く説明する
### 1. スプレッドシートを作成
スプレッドシートを作成し、日付を入力する列(Date)、説明を入力する列(Description)、イベントとしてカレンダーに追加済みであるかを明示する列(Added)を作成
ある行について、その行のイベントがカレンダーに追加済みの場合、その行のAdded列に`TRUE`が表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734184/2fbac9d5-6ca3-c4ed-936c-179f7004e48c.png)


### 2. スクリプトエディタでコーディング
上部メニューの「拡張機能」の「App Scirpt」からスクリプトエディタに飛ぶ
以下のソースコードを入力する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734184/bc37069b-d0eb-7b65-e476-220384469022.png)


#### ソースコード
```JavaScript
function registCalenderEvent(){
  let myCalendar = CalendarApp.getCalendarById("MAILADDRESS"); //自分のメアドを入力
  let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SHEETNAME"); //使うシートの名前を入力
  const now = new Date(); //現在時刻を取得
  for(let i = 0; i < sheet.getLastRow() - 1; i++){
    const TF = sheet.getRange(i + 2, 3).getDisplayValue(); //スプレッドシートのある行に対して、それのイベントが作成済みであるかを確認する変数を宣言
    if(TF == "TRUE"){
      continue; //イベント作成済みならcontinue
    } else {
      const data1 = sheet.getRange(i + 2, 1).getDisplayValue(); //スプレッドシートから日付を取得
      const data2 = sheet.getRange(i + 2, 2).getDisplayValue(); //スプレッドシートから説明欄に入力する説明を取得
      const data3 = sheet.getRange(i + 2, 3); //イベント作成済みであるか否かを判別するセルの参照を変数に割り当てる
      const TargetDate = new Date(data1); //Date型のオブジェクトに変換
      TargetDate.setFullYear(now.getFullYear()); //スプレッドシートから取得した日付に現在の西暦を設定
      const options1 = {
        description: "説明 : \n" + data2 //説明欄に記入する内容を格納するオブジェクトを宣言
      }
      myCalendar.createAllDayEvent("O", TargetDate, options1);
      const options2 = {
        search: "説明 : \n" //作成したイベントを探す為の文字列を格納するオブジェクトを宣言
      }
      let createdEvents = myCalendar.getEventsForDay(TargetDate, options2); //色を割り振る為に、作成されたイベントを取得
      createdEvents[0].setColor("6"); //イベントにORANGEカラーを割り当てる
      data3.setValue("TRUE"); //イベントが作成済みであることを示す文字列をスプレッドシートに追加
    }
  }
}
```

参考 : [公式リファレンス](https://developers.google.com/apps-script/reference)(英語)

### 3. スクリプトを実行しやすくする為にスプレッドシート上にボタンを配置
上部メニューの「挿入」の「図形描画」からボタンのデザインを決定し、作成したボタンの右上の三点リーダーから「スクリプトの割り当て」を選択し、先程作成した関数名を選択
ついでに、条件付き書式でAdded列の各セルについて、値が挿入されているときに色を付けるようにした
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734184/a09aca98-80a1-5df6-2a25-f587029d9a31.png)

これで作成したボタンを押すだけでスクリプトが実行されるようになった
Smart Maps コミュニティ・バリュー・ステートメント

2022年9月29日に、国連オープン GIS イニシアティブにドメイン作業グループ(DWG) 7 「Smart Maps」が発足しました。このグループは[プロジェクトドキュメント](https://github.com/UNopenGIS/7/wiki/Project-Document)を参照しながら活動を進めていきます。このエントリでは、このプロジェクトの中にある[コミュニティ・バリュー・ステートメント](https://github.com/UNopenGIS/7/wiki/Project-Document#community-value-statement)に解説を入れていきます。

### ベクトルタイルの設計・生産・スタイル・ホスト・最適化を支える
DWG7 on Smart Mpas のミッションは「ウェブ地図をオープンに保つ」ことです。このために、ウェブ地図に表示する地図データであるベクトルタイルを、設計・生産・スタイル・ホスト・最適化する方法を共有していきたいと思っています。

共有の具体的な方法は、コード、ドキュメント、デモ、能力構築、になると思っています。実際に技術を発揮し、発揮した技術を体系化していくのが有効だと思っています。

国連ベクトルタイルツールキット (United Nations Vector Tile Toolkit: UNVT)　は主にこの価値を実現するために進めてきたプロジェクトであり、引き続き、UNVT は DWG7 on Smart Maps でホストされ続けます。

### 資源の限られた環境でこなすことを支える
国連オープン GIS　イニシアティブの第一目的は国連活動に必要なオープンソース GIS バンドルを特定し実装すること、第二目的は世界のオープンソース GIS の実効性と効率を高めることです。

いずれの目的のためにも、環境を選ばずに広く動作するウェブ地図を実現することが有効だと思っています。

具体的には、Raspberry Pi で UNVT を動作させる UNVT Portable を用いて、デモや能力構築を進めてきているところであり、引き続き、活動を進めていきます。

### ユースケース収集を支える
ウェブ地図には汎用性があるために、回る事業に転換することが難しいです。

幅広くユースケースを把握することができれば、回る事業につながるようなユースケースを選び取る可能性も高まりますし、あるいは、多くの有望ユースケースを横断的にカバーするようなアーキテクチャを考えることができる可能性も高まります。

DWG7 on Smart Maps は、単に開発やドキュメント、デモを進めるための場所となるだけではなく、ウェブ地図のユースケースを収集する目的を持った参加者の役にも立てるようになりたいと思っています。

### 楽しむことを支える
Linus Torvalds　的な観点からも、Audrey Tang 的な観点からも、fun というコンセプトは戦略的に重要です。参加のレベルを高め、悪意を抑え、しかも参加の幅を広げることができる気がします。なにより、私自身が楽しみたいです。

活動の端々に fun というコンセプトを埋め込んでいきたいですし、具体的にはどのように fun の溢れるコミュニティを作っていけるか常に考えていきたいと思っています。

### 新しい考えを伝えることを支える
我々は、地図技術者が地図技術者として生きていける世界を作りたいです。そのためには、地図技術者の考えが理解される、伝えられるコミュニティが必要だと思っています。

地図技術者として新しい考えが浮かんだときに、それを話せる場所がなければ、その考えを育てて実装していくことは非常に難しくなります。地図技術者が自分の考えを話し、壁打ちができる場所を提供できればと思っています。

### 助け合うことを支える
DWG 7 on Smart Maps は、目標を持ち寄って一緒に進んでいくタイプのグループです。ウェブ地図はデータからソフトウェアを使ってサービスを組み上げていく仕事ですから、例えばソフトウェアをシェアする、あるいはデータをシェアする、サービスに組み上げるノウハウを共有する、といった方向で助け合うことができます。

考えを伝え合った上で、それぞれの多様な立場を尊重し合いながら、要求ではなく共感と信頼によって、助け合っていくことができればと思っています。

### 画像や標高、点群や三次元都市モデルも扱うことを支える
DWG 7 on Smart Maps の母体は UNVT であり、UNVT 主要対象である基本図（base map)はさまざまなアプリケーションの共通要素となる主翼のようなものです。

他方で、空中写真や衛星画像のような画像、伝統的なデータや新しいデータから作った標高、三次元点群（ポイント・クラウド）や三次元都市モデルは、そういった主翼に組み合わせ、用途に応じて機能を発揮するフラップのような機能を持っています。

主翼が主翼として機能するためにも、フラップを自在に出せる状況を作っていく必要があります。DWG 7 on Smart Maps では、そのような発想から画像や標高、点群や三次元都市モデルも扱うことを支えていければ、と私は考えています。

もちろん、違った考えやアプローチもあって良いところであり、そういった考え方やアプローチを共有いただけるばとして DWG 7 on Smart Maps が使われれば光栄だと思っています。

## 紹介: FOSS4G Thailand 2022 での講演
2022年11月25日に FOSS4G Thailand 2022 で講演する機会をいただきました。その時の[スライドを Speakerdeck で公開](https://speakerdeck.com/hfu/introduction-to-vector-tiles)しています。
ZennにGitHub上の画像を表示させる方法

ZennにGitHub上の画像を表示させる方法を紹介します。

すでにZennに記事を保存してあることが前提です。

記事を保存していない人は、とりあえず記事を書いて保存してください。

なお、ZennだけでなくQiitaにも同じ方法でGitHub上の画像を表示させることができます。


## 準備  その1

事前にZennとGitHubを連携させておきます。

やり方はこちら。

**ZennとGitHubを連携させる方法 - Qiita https://qiita.com/akiba_burari/items/2423d284bab666e01f45**

https://qiita.com/akiba_burari/items/2423d284bab666e01f45

## 準備  その2

事前にZennのGitHub共有リポジトリに画像をアップロードしておきます。

やり方はこちら。

**ZennのGitHub共有リポジトリに画像をアップロードする方法 - Qiita https://qiita.com/akiba_burari/items/de7f6214f0b4ef94a646**

https://qiita.com/akiba_burari/items/de7f6214f0b4ef94a646


## GitHubにアクセス

GitHubにアクセスし、表示させる画像を選択します。

**画像の上で右クリック→「画像アドレスをコピー」を選択**

画像のURL（アドレス）をメモしておきます。

例：

**https://github.com/AkibaBurari/zenn_connect/blob/main/images/retoro-arck-top.png?raw=true**

## 記事内に画像を挿入する

記事内に画像を挿入するには以下のように絶対パスを指定します。


![](/images/example-image1.png)


例：
```
![](https://github.com/AkibaBurari/zenn_connect/blob/main/images/retoro-arck-top.png?raw=true)
```



## Zennにアクセス


Zennにアクセスし、自分のアイコンをクリック

「記事の管理」を選択

記事タイトルの横にある鉛筆アイコンをクリックし、保存した記事を開きます。

記事内にコードを挿入します。

```
![](https://github.com/AkibaBurari/zenn_connect/blob/main/images/retoro-arck-top.png?raw=true)
```

※プレビューしても画像は表示されません。

「**内容を更新**」ボタンを押し、記事を保存して閉じます。

記事が公開されると、画像が表示されているのが確認できます。

![](https://github.com/AkibaBurari/zenn_connect/blob/main/images/retoro-arck-top.png?raw=true)



## 参考サイト  一覧

GitHubリポジトリ連携で画像をアップロードする方法 https://zenn.dev/zenn/articles/deploy-github-images
テストエンジニアが意識すべき考え方について

# はじめに

8年ほどゲームテストのお仕事に関わってきました、@tomsakです。
この記事では、これまでテスト業務に携わってきて
テスター、テストリーダー、マネージャーを経てきた中で大事だなと感じた考え方について
つらつらと書いていきます。

テストエンジニアを目指したい方以外にも参考になるものもあるかと思います。
良ければ最後までお付き合いください。



# PREP法
ソフトウェア開発やテストのお仕事をしていると、切っても切れないのがバグレポート。
その内容をうまく伝える手法の一つがPREP法です。

バグレポートは、プログラム開発者にどういった問題が起きているか簡潔に伝えることが大事ですが、
それがうまく活用できないと
* バグの修正がうまくいかない
* 品質状況が正確に把握できない
* コミュニケーションコストの増大
といったことに繋がります。

そうならないためにPREP法を意識するのはとても大事です。
ちなみに、「PREP」とは以下の英単語の頭文字から取られています。

* __Point__　　__結論__
* __Reason__　 __理由__
* __Example__　__具体例__
* __Point__　　__結論__

結論から記述して、
その後に理由や、経緯、発生環境、期待される結果…など詳細を書いていくということですね。

人間って意外と文章の頭の方しか読んでいなかったり、
会話だと最初の30秒程度が一番集中力をもって聞いていたりするそうなので
文章だけでなく、会話においても重要かと思います。

例えば上司への業務報告をする際にも有効ですし、
自分が報告を受ける立場の時も「結論→理由」と続いた方が内容が入ってきやすいです。
「経緯→結論」「理由→結論」のように頭でっかちな文章・会話だと「何言ってるかよくわかんない…」と感じることもしばしばです。



# 意識してインプットする・勉強する

２つ目は、知識の意識的なインプットについて。

これは直接的に業務に関わる知識・スキルに留まらないのですが
ゲーム業界に居る人はゲーム関連のニュースや、業界動向は常に目を通すようにしたり、
新しい知識を積極的にインプットしていくことが大事だなと思います。

新しい知識や技術は、分かりやすいカタチに「調理」されてくるのが遅かったり
特にテスト知識などは社内研修等に取り込まれるまで時間がかかります。
普遍的なスキル・知識は既に分かりやすくまとめられたモノを吸収していけばそれで十分ですが、
ゲーム業界は常に新しい技術や表現が生み出されたり、取り込まれていると個人的に思っていまして、
会社や組織に頼って待っているだけだと出遅れます。


恐ろしいのは、天才と呼ばれる人・仕事が出来る人というのは
これらを努力と意識しなかったり、苦にも感じず自然とこなせてしまうことです。
私は凡人なので常に意識してアンテナを張り巡らせ、
落ちている情報を拾いに行き、取捨選択し、自分の知識にしていく必要があるな…と日々感じています。


# 自分の考えをアウトプットする

３つ目は、書き出してみる、第三者と話してみる、発信するということです。

業務上の機密情報まではさすがに話すわけにはいかないですが、

自分の考えていることや、課題に感じていること、悩みなどは一人で頭の中で考えているよりも
文章にしたり図を書いて整理してみたり、
同僚に話すことで頭の中が整理されたり、
更には一緒に考えてもらうことで解決に向かう可能性も高まるので、一人で抱え込んでいる必要はないと感じます。

あるいは自分の日々考えていることをアウトプットし、発信していくことで
発信したからこそ意見がもらえたり、指摘をもらえたり、より建設的な方向に進むと思います。
人前で何かを発信するのは、初めは勇気の要ることですが
人に向けて自分の考えを発信するということは自信にも繋がると思います。



# さいごに
いかがだったでしょうか。
まとめると「__伝え方__」「__インプット__」「__アウトプット__」が大事ということですね。

仕事に忙殺されていると これらが頭からすっぽ抜けている時もありますが、
過去を振り返ってみると
これを意識的・無意識的に出来ている時が特に業務がうまく回っていたと言える気がします。

こういう考え方も大事だと思う、というご意見などありましたら
是非コメントで教えていただけると嬉しいです。

最後まで読んでいただきありがとうございました！
PHPUnit10 を Composer の /src 直下で動かしたい時

趣味のレベルの話です。

## PHPUnit の Github のコードが 10 のものになっている

PHPUnit は 結構大きいプロジェクトな気もするのに、個人プロジェクトになっていて、その最新のコードも 10 になってしまっている。

https://github.com/sebastianbergmann/phpunit

10 だと結構変更点が多くて、TestCase のメインのメソッドである `run()` が 9までだと TestResult を返しているのに、10 だと void になっていたりする。

この 10 をデバッグ用に、composer で言うところの /src 直下から実行したい場合に、少しハマったので、その方法を説明します（普通にtest フォルダを作って、`/vendor/bin/phpunit ./test`でも動きます）。

## PHPUnit10 を /src 直下から動かす

まずは、PHPUnit10 をインストールしましょう。
composer でプロジェクトを作ってから、composer.json に以下の内容を追加します。

```json:composer.json
    // 省略
    "minimum-stability" : "dev",
    // 省略
    "require": {
        "phpunit/phpunit": "10.*"
    }
```

これで インストールすると、JUnit10 がインストールされます。
ここでは、JUnit10 の Framework を使います（JUnit4 と比べるとPHPUnit の Framework は大分量が多くなっています）。

今回は、こちらのページからテストケースを拝借してきました。

https://note.kiriukun.com/entry/20190804-trying-to-use-composer

テストコードは、src 直下におき、TestCase を継承したクラスから、`run()` を呼び出して、テストを実行します。

```php:ChickTest.php
<?php

require 'vendor/autoload.php';

use PHPUnit\Framework\TestCase;
use YourUserName\YourPath\Chick;
use YourUserName\YourPath\Feed\Worm;

class ChickTest extends TestCase {
	public function testEat() {
		$chick = new Chick();
		
		$chick->eat(new Worm());
		$this->assertSame(1, $chick->getEatCount());

		$chick->eat(new Worm());
		$this->assertSame(3, $chick->getEatCount());
	}
}

$chickTest = new ChickTest("testEat");
$chickTest->run();
```

## 謎のエラー

ですが、このままだと動きません。下のようなエラーが出てきます（ちょっと行数が違うかもしれませんが）。

![スクリーンショット 2022-11-30 22.33.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92647/07aa0523-77b2-a35b-1ac1-c8302624f4c9.png)

これを直すには、`PHPUnit\TextUI\Configuration\Registry` にパッチを入れる必要があります。
まず、`PHPUnit\TextUI\Configuration\Registry` のファイルがある `/vendor/phpunit/phpunit/src/TextUI/Configuration/Registry.php` に以下のようなライブラリインポートのコードを入れます。

```php:Registry.php
use PHPUnit\TextUI\CliArguments\Builder as CliBuilder;
use PHPUnit\TextUI\XmlConfiguration\DefaultConfiguration as XmlBuilder;
```

その後で、get メソッドを以下のように変えます。

```php:Registry.php
    public static function get(): Configuration
    {
        $cli_conf_builder = new CliBuilder();
        $cli_conf = $cli_conf_builder->fromParameters(array(), array());
        $xml_conf = XmlBuilder::create();

        $conf_merger = new Merger();
        $merged_conf = $conf_merger->merge($cli_conf, $xml_conf);

        self::$instance = $merged_conf;

        assert(self::$instance instanceof Configuration);

        return self::$instance;
    }
```

これで、今回は直ります。一応、デフォルトの設定にしているだけなので多分大丈夫でしょう。

あとは、`echo` や `print` を `run` や `runBare` 辺りに入れて、どう動いているか試すだけです。
【MySQL】ERROR 1046 (3D000): No database selected 解消法

## 状況

DockerのMySQLのコンテナ内にて以下のように実行したところ表題のエラーが発生しました。  

```terminal
$ mysql> show tables;
ERROR 1046 (3D000): No database selected

```

## 解消法

以下のコマンドで使用するデータベースを選択したところ解消しました。

```terminal
$ mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| sample             |
| performance_schema |
+--------------------+
3 rows in set (0.00 sec)

$ mysql> use sample
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
$ mysql> show tables;
+-------------------------+
| Tables_in_sample        |
+-------------------------+
| ar_internal_metadata    |
| samples                 |
| schema_migrations       |
+-------------------------+
3 rows in set (0.01 sec)
```
Leetcode 744. Find Smallest Letter Greater Than Target

# 744. Find Smallest Letter Greater Than Target

https://leetcode.com/problems/find-smallest-letter-greater-than-target/
## 難易度
### Easy


## アプローチ
### 二分探索

```java
class Solution {
    public char nextGreatestLetter(char[] letters, char target) {
        int letters_length = letters.length;
        int low = 0;
        int high = letters_length - 1;

        if (target < letters[low] || target >= letters[high]) {
            return letters[low];
        }
        while (low <= high) {
            int mid = low + (high - low) / 2;
            if (target < letters[mid]) {
                high = mid - 1;
            }
            if (letters[mid] <= target) {
                low = mid + 1;
            }
        }
        return letters[low];
    }
}
```
reg-cliを使って手元で簡単にビジュアルリグレッションテストを行う

## はじめに
リリースを行った際に元のページとリリース後のページを比較して差分を確認したいと思い、reg-cliを活用して手元でビジュアルリグレッションテストを動かせないかと考えました
reg-cliを利用すれば簡単に実装できそうだったので、実際に作ってみました

https://github.com/reg-viz/reg-cli

## 1. 画像を取得する
1枚ずつ手動でスクリーンショットを撮影することもできますが、かなりの手間なのでPuppeteerを利用してスクリーンショット撮影を自動化しました

スクリーンショット撮影部分は以下のようになっています
```javascript:src/scraping.js
const puppeteer = require('puppeteer')
const websites = require('../websites.json')

const screenshot = async (key, dir) => {
  const browser = await puppeteer.launch({
    args: [
      '--disable-gpu',
      '--disable-dev-shm-usage',
      '--disable-setuid-sandbox',
      '--no-first-run',
      '--no-sandbox',
      '--no-zygote',
      '--headless'
    ]
  });
  const page = await browser.newPage();
  page.setViewport({width: 1200, height: 1600});
  await page.goto(websites[key])
  await page.screenshot({
    path: `image/${dir}/${key}.png`,
    fullPage: true
  });
  page.waitForTimeout(1000)
  await browser.close()
}

(async () => {
  const dir = process.argv[2] || 'expected'
  for (const key in websites) {
    await screenshot(key, dir);
  }
})();
```

website.jsonにはスクリーンショットを撮影するURLと保存する画像の名前をkeyにした一覧を入れていました
```json:website.json
{
  "example":"https://example.com",
  "example2":"https://example.com"
}
```

上記を実行して`image/actual/`に画像を保存します
```sh
node src/scraping.js actual
```

#### 気をつけないといけない点について
今回スクリーンショットを撮影したページでは問題なかったのですが、画像を遅延読み込みしている場合は画像が読み込まれていない状態でスクリーンショットが撮影されていまいます。
もしページ内の画像もスクリーンショットに含めたい場合には、スクリーンショットを撮影する前に一番下までスクロールをしたあと一番上まで戻ってくる処理を含める必要があります

### 2.reg-cliの実行
#### reg-cliの導入
yarnやnpmを使ってインストールを行ってください
```sh
yarn add reg-cli
```

#### テストの実行方法
テストの実行前に`images/expected/`の画像を更新します
```sh
node src/scraping.js
```

`image/actual/`の画像と`/image/expected/`に保存された画像をもとに比較を行います
```sh
yarn reg-cli ./image/actual ./image/expected ./report/diff -R ./report/report.html

# -Uオプションをつけるとテスト実行後にexpectedの画像がactualにコピーされます
yarn reg-cli ./image/actual ./image/expected ./report/diff -R ./report/report.html -U
```

`/report/report.html`に結果が出力されるので、ブラウザなどで確認してください

### まとめ
手軽に手元でビジュアルリグレッションテストを行う環境ができました
意図しない変更がないか手軽に確認できるようになったので、不具合を減らすことができそうです
Svelte + Vite環境で、svelte-routingを使い、パスルーティングを実装する

# はじめに

svelteJSを使ってアプリケーションを構築しており、
routingの実装を[svelte-routing](https://github.com/EmilTholin/svelte-routing)で実装したのでその時のメモ。

# 使ったもの

* Vite + Svelte + Typescript
    * svelte-routing

## 前提
Dockerベースイメージ`node:18-alpine3.15`で構築

## 導入
1. Vite + Svelte環境構築
    
    ```bash
    $ npm init vite@latest
    ✔ Project name: … <任意の名前>
    ✔ Select a framework: › Svelte
    ✔ Select a variant: › TypeScript
    
    $ npm install
    ```

1. vite.config.tsを修正
    
    ```typescript
    import { defineConfig } from 'vite'
    import { svelte } from '@sveltejs/vite-plugin-svelte'
    
    // https://vitejs.dev/config/
    export default defineConfig({
      plugins: [svelte()],
      server: {       // 追加
        host: true,   // 追加
        port: 8080    // 追加
      }               // 追加
    })
    
    ```

1. サーバー起動

    ```bash
    $ npm run dev
    ```

    これで[localhost:8080](http://localhost:8080)で環境が開けるはず

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/556a79a6-5a6c-4953-86aa-6e0cf6272ddb.png)

    こんな画面

1. svelte-routingのインストール

    ```bash
    $ npm install --save svelte-routing
    ```

# svelte-routingの使い方

```vue
<script lang="ts">
  import { Router, Link, Route } from "svelte-routing";  // svelte-routingの読み込み
</script>

<Router>
  <nav>
    <Link to="home">Home</Link>
    <Link to="about">About</Link>
  </nav>
  <div>
    <Route path="home"><Home /></Route>
    <Route path="blog" component="{Blog}" />
  </div>
</Router>
```

* `Router`コンポーネントの中で`Link`や`Route`を書いていきます。

## Link

* イメージとしては`<a href="">`みたいな感じ
* クリック後、to=""で指定した先に遷移します。
* 基本的に`to="about"`と書くと現在のパスに追加でパスが増えていく。(同じRouterコンポーネント内では置き換わる)
* `to="/page/about"`のように絶対パスで指定することも可能
* また、`to="../about"`のように相対パスでもかける

```vue
// http://localhost/home

<Link to="about">About</Link>
// ⇒ http://localhost/home/about

<Link to="/about">About</Link>
// ⇒ http://localhost/about

<Link to="../about">About</Link>
// ⇒ http://localhost/about
```
## Route

* 該当パスの時の表示コンポーネントを指定
* コンポーネントが指定されていないときは子の要素がレンダリングされる

```vue
<script lang="ts">
  import About from "./About.svelte";
  import Blog from "./Blog.svelte";
</script>

<Route path="about" component="{About}" />
<Route path="blog">
  <Blog />
</Route>
<Route path="/">
  <h3>メニューを選択してください。</h3>
</Route>
```

## その他

`navigate`なども用意されており、ログイン後の遷移なども行えて便利そうです。

```vue
<script>
  import { navigate } from "svelte-routing";

  function onSubmit() {
    login().then(() => {
      navigate("/success");
    });
  }
</script>
```

それぞれいろいろな`Properties`が用意されているのでいろいろ使ってみたいです。
nuxt(javascript)からlaravelへapiで配列データを渡す

# やりたいこと
nuxt(javascript)からlaravelへapiで配列データを渡したい。

# 結論
jsからapiへ渡すときはこうなる

```js:JavaScript
for (let i = 0; i < this.formData.length; i++) {
 formData.append('files[]', this.formData.files[i])
 formData.append('file_infos[' + i + '][title]', this..formData.files[i].title)
 formData.append('file_infos[' + i + '][outline]', this.formData.files[i].outline)
}

// これで
// [0] => array[
// title => ‘たいとる’,
// outline => ‘がいよう’;
// ]
// として受け取れる

// 下記はできそうでできない(なぜかnull)になる
// const array = [
//  title: this.formData[i].title
//  outline: this.formData[i].outline
// ]
// formData.append('file_infos[' + i + ']',ary)
```

# 解説
Object.keysと
some関数を使用する

ちなみにバリデーションでは
```php:laravel
'file_infos.*.title'    => [
 'required',
 'string',
],
'file_infos.*.outline'    => [
 'nullable',
 'string',
]
```

のような記述になる。
laravel公式ドキュメントにも記載されています。
公式リンク
https://readouble.com/laravel/8.x/ja/validation.html
Pythonでファイルの文字コードを自動判別

## 背景
### 文字コードでエラーになる
皆さんはPythonを実行する際に、読み込んだファイルの文字コードが予定したものと違ったということはありませんか？
私はpipのライブラリ一覧をエクスポートした際に「UTF-8」と「UTF-16」になるということがあったので、備忘録として残しておきます。


## 自動で文字コードを判別するために
### 使用したライブラリ
**chardet**というライブラリを使用することによって解決できました。
公式ドキュメント：https://chardet.readthedocs.io/en/latest/

### ライブラリをインストール
> $ pip install chardet

### コードサンプル
```python
from chardet import detect
 
# まず対象ファイルをバイナリーで読み込む
with open("<対象ファイル>", 'rb') as bf:
    binary_data = bf.read()
    encode_data = detect(binary_data)

# 再度ファイルを開く、この際に上記で調べてエンコードを代入する
with open("<対象ファイル>", mode='r', encoding=encode_data['encoding']) as f:
    pass
```

## 最後に
これでExcelファイルからCSVを作成した際に、文字コードをいちいち開かず確認が済みますね！
MakefileでOS毎に異なる処理を実行したい時の方策を考える

# 事の起こり
UNIX系OSを利用していると様々なdotfileが育っていきます．`.bash_profile`, `.bashrc`, `.vimrc`等々です．筆者はこれらのファイルをGitで管理しています．自宅ではMacとLinuxを利用しているので様々なdotfileを管理していますが，これまでMac用，Linux用各々のリポジトリで管理していましたが，管理が非常に煩雑になってきました．よって1つのリポジトリでディレクトリで切り分け，dotfileのシンボリックリンクを張る時にOS毎に異なるファイルのリンクを張れる様にMakefile上で実行しているOS情報を取り出し，条件分岐で切り分ける処理が実装出来れば煩雑さが軽減しそうです．

# ディレクトリ構造

```bash
dotfiles/
├── Makefile
├── linux
└── mac
```

# 実装方法
UNIX系OSでは`uname -s`でOS名が取り出せます．よって，コマンドの実行結果を変数に代入し，OS毎に処理を切り分けます．

```makefile:実装例
os := $(shell uname -s)

all:
ifeq ($(os),Darwin)
	cd mac && make -f Makefile_mac
else ifeq ($(os),Linux)
	cd linux && make -f Makefile_linux
else
	echo Error: This system may be incompatible!!
	@exit 1
endif
```

:warning: 別々に管理していた頃の名残で各々のOS用のMakefileを用いてリンクを張っていますが，直接リンクを張る処理を実装する方法でも良いと思います．

:warning: 1行目で変数`os`にOS名を代入していますが，`:=`を用いて代入しています．`=`を用いた場合は，変数`os`の値が評価される度に代入処理が実行されます．

:warning: `else ifeq`は古いバージョン(3.8.1以前)のMakeでは利用出来ません．

:warning: エラー終了は`@exit 戻り値`で設定します．

## 実行方法
実行方法は簡単です．上記のディレクトリ構造における`dotfiles`ディレクトリ内でMakeを実行するだけです．

```bash
make
```

# まとめ
Makeは非常に歴史有る開発ツールですが，様々な場面で活用出来る有用なツールだと筆者は思っています．今後も色々と試しつつ活用の幅を広げていきたいと思っています．

# Reference

https://www.nullpo.io/2021/05/04/shellscript-make-shell/

http://masahir0y.blogspot.com/2012/10/make-380-make-381.html

http://masahir0y.blogspot.com/2012/06/makefile.html

http://quruli.ivory.ne.jp/document/make_3.79.1/make-jp_5.html

https://ksaito11.hatenablog.com/entry/2020/04/24/102112

https://www.web-dev-qa-db-ja.com/ja/makefile/%E3%83%A1%E3%82%A4%E3%82%AF%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AB-%27cd%27%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92%E6%9B%B8%E3%81%8F%E3%81%AB%E3%81%AF%E3%81%A9%E3%81%86%E3%81%99%E3%82%8C%E3%81%B0%E3%81%84%E3%81%84%E3%81%A7%E3%81%99%E3%81%8B%EF%BC%9F/969000466/
AWS SDK V3 + Lambda を SAM deploy した際の "Could not resolve" の対処法

# 背景
SAM で EventBridge Trigger + Lambda を Deploy しようとしてる

その際に発生したエラーの対処法の記録

## エラー内容
最初は npm install かと思ったけど、Esbuild の話でそこそこ悩んだ
```powershell: Esbuild error
Error: NodejsNpmEsbuildBuilder:EsbuildBundle - Esbuild Failed: X [ERROR] Could not resolve "@aws-sdk/lib-dynamodb"
    app.ts:2:27:
      2 │ import { PutCommand } from "@aws-sdk/lib-dynamodb";
        ╵                            ~~~~~~~~~~~~~~~~~~~~~~~
  You can mark the path "@aws-sdk/lib-dynamodb" as external to exclude it from the bundle, which will remove this error. 
```
## 解決策
エラーメッセージ通りで、Esbuild の Bundle 対象から外せばいいだけでした。

具体的には、template.yaml の BuildProperties に、以下のように External: を追加すればOKでした。

```yaml: template.yaml
    Metadata: # Manage esbuild properties
      BuildMethod: esbuild
      BuildProperties:
        Minify: true
        Target: "es2020"
        Sourcemap: true
        EntryPoints: 
          - app.ts
        # ★ここを追加★
        External:
          - "@aws-sdk/lib-dynamodb"
          - "@aws-sdk/client-dynamodb"
```

### Document
説明は以下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/b0af59b8-f474-3843-760e-fd918fa91626.png)

https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/serverless-sam-cli-using-build-typescript.html

:::note warn

日本語版は機械翻訳で、Properties も一緒に翻訳されてるので注意
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/964aaf89-1c72-3dc4-5289-fa1d100d20a2.png)
:::

## その他の確認内容
解決に至るまでの調査内容
### インストールし忘れ？かと思い試すがダメ
```powershell: インストール
npm install @aws-sdk/lib-dynamodb
```

### dependencies のせい？でもなし
stackoverflow で検索したらV2 の頃の同じエラーがあったので、以下二点試すもダメ
※対象 URL 逸失

- Dev Install を試すがダメ（uninstall 後）
    - dependencies > devDependencies と理解
```powershell: Dev Install
npm install -D @aws-sdk/lib-dynamodb
```
- Optional Install & Omit を試すがダメ
    - optionalDependencies & npmrc で、`omit[]=optional` 追加　と認識
```powershell: check
npm install -O @aws-sdk/lib-dynamodb
```
```node: npmrc の設定
omit[]=optional
```
#### npmrc の現状動作の確認と、全オプションの初期値付き編集
:::note info
現在の npmrc の読み込み状況を調べる
`npm publish --dry-run --verbose`
:::

:::note info
npm の config 設定を編集
- これで開くと、option default が列挙されるのでわかりやすくて Good :heart_eyes: 
`npm config -g edit`
- `-g` を付けるかは状況次第
:::

### SAM validate してみたら、region が抜けてたけど、region 追加してもダメ
確認して
```powershell: sam validation
sam validate
```
.aws/config に region 追加

### error 内容に従って、build --exclude
変わらず
```powershell: exclude
sam build --exclude @aws-sdk/lib-dynamodb
```


# あとがき
AWS-SDK V2 の情報はたくさん見つかるけど、V3 用を探すのが面倒・・
少し慣れて V2/V3 を見分けられるようになったけど、最初はきつかった

:::note info
V2/V3 の見分け方

SDK|import 名|例|補足
-|-|-|-
V2| `aws-sdk`|`import * as AWS from 'aws-sdk';`|
V3| `@aws-sdk/{service}` |`{import { S3Client } from '@aws-sdk/client-s3';`|サービス単位
:::
PHPの名前空間について

## はじめに

日本システム開発株式会社の藤井といいます。
今回は名前空間についてまとめてみました。

## 名前空間とは

クラス、関数...をグループ化する機能です。
PHPタグの次の行で`namespace hoge`と宣言することで、それ以降の定義はすべてその名前空間(グループ)に属します。
名前空間を使うことでクラス、関数をグループごとに管理できます。

## 使い方

hoge.php

```php
<?php
namespace Hoge;

class fizz{
    function __construct() {
        echo "hogeFizz" . PHP_EOL;
    }
}
?>
```

foo.php

```php
<?php
namespace Foo;

require "hoge.php";

class buzz{
    function __construct() {
        echo "buzz" . PHP_EOL;
    }
}

$fizz = new \Hoge\fizz();
$fizz = new buzz();
?>
```

`require "hoge.php"`で名前空間Hogeのfizzクラスをfoo.phpに読み込みます。
先頭に`\`を付けた完全修飾名で、名前空間Hogeのfizzクラスを指定しています。

## グローバル空間、サブ名前空間

名前空間の宣言(namespace)が存在しない場合、そのファイルのクラス、関数...はグローバル空間に属します。
グローバル空間にはPHPの定義済みクラス、関数が存在します。

名前空間はネストすることが可能で、`namespace Foo\Bar`は名前空間Fooのサブ空間Barとなります。

## 名前空間内でのクラス呼び出しの解決

完全修飾名
　先頭に`\`を付けた呼び出しは、グローバル名前空間を基準に解決されます。
　`\Foo\Bar\fizz`の形式。`\Foo\Bar\fizz`に解決される。
修飾名
　先頭以外に`\`を含む呼び出しは、現在の名前空間を基準に解決されます。
　`Bar\fizz`の形式。`現在の名前空間\Bar\fizz`に解決される。
非修飾名
　どこにも`\`を含まない呼び出しは現在の名前空間で解決されます。
　`fizz`の形式。`現在の名前空間\fizz`に解決される。

## useを使ったクラスのインポート/エイリアス

useを使うことで前のfoo.phpを書き換えることができます。

foo.php

```php
<?php
namespace Foo;

require "hoge.php";

use Hoge\fizz;

$fizz = new fizz();
$fizz = new fizz();
?>
```

useを使うとHoge\fizzをFoo\fizzのように使えます。(インポート)
useを使うことで完全修飾名を使う必要がなくなり、簡潔に書くことができます。

useを使うとHoge\fizzを現在のFooにインポートしますが、Foo内のクラスとの重複を避けるためエイリアスをつけられます。

foo.php

```php
<?php
namespace Foo;

require "hoge.php";

use Hoge\fizz as hogeFizz;

class fizz{
    function __construct() {
        echo "fooFizz" . PHP_EOL;
    }
}

$fizz = new HogeFizz();
$fizz = new fizz();
?>
```

## 定義済みのクラス

PHPにはStdClassなどの定義済みクラスがあります。
名前空間を使わない場合は、`new StdClass()`で呼び出せますが、
名前空間を使うと、先頭に`\`のない呼び出しは現在の名前空間を基準に呼び出します。
そのため、定義済みクラスは`new \StdClass()`で呼び出します。

```php
<?php
namespace Huge;

$std = new \StdClass();
var_dump($std);

// useでのインポートも可能です
use StdClass;
$std = new StdClass();
var_dump($std);
?>
```

## psr-4

autoloadするための仕様のことです。

autoloadとは、
クラスを呼び出したタイミングで、そのクラスが見つからなかった場合にクラスの完全修飾名から
ファイルを自動的にロード(include)するための枠組み

具体的には、spl_autoload_registerでロード用の関数を登録し、クラスが見つからなかった場合にその関数が呼び出される。
psr-4はロード用の関数の仕様で、名前空間とディレクトリを紐づけることで、独自のディレクトリ構造からファイルをロードできる。

```php
<?php
namespace Foo;

use Hoge\huga\fizz;

$fizz = new fizz;
?>
```

Hoge\huga\fizzはどこにも定義されていないため、クラスが見つからずエラーになる。
spl_autoload_registerで登録した関数は、このタイミングで呼び出される。

composer.jsonのautoload

```json
"autoload": {
    "psr-4": {
        "Hoge\\": "app/"
    }
}
```

composerのpsr-4を用いるとHoge\huga\fizzへのアクセスは、
Hogeがappディレクトリに変換され、app\huga\fizz.phpをautoloadします。

autoloadと名前空間は別の機能のため、autoloadしたファイルで該当の名前空間(Hoge\huga)
が宣言されていない場合、クラスへのアクセス(new fizz)はエラーになります。

## まとめ

- 名前空間とはクラスや関数...をグループ化し管理する機能
- 名前空間内からのクラスや関数...へのアクセスは、完全修飾名、修飾名、非修飾名のいずれかを用いる
- useを使うことで、異なる名前空間にあるクラスや関数...を現在の名前空間にインポートできる
- psr-4とはautoloadの仕様で、名前空間とディレクトリを紐づけロードするファイルを見つける
Java　基本の基本２

# はじめに
自身でprogataやスクールでJavaを勉強中。学んだことをアウトプットして、より定着させるために記事にまとめていきます。継続は力なり！

# 基本データ型
変数に格納する中身によって、データ型を指定しなければならない。
- 整数型
byte, short, int, long
intが一般的

- 浮動小数型
float, double
doubleが一般的

- 文字型
char
※Stringは文字列。基本データ型ではない。よって最初が大文字。

- 真偽値
boolean
(true / false)を格納。二者択一の情報。

# データ型
## 参照型
（文字列型、配列、列挙型、クラスインスタンスなど）
基本データ型は変数に値そのもののデータを格納しているが、参照型は変数に格納するデータの位置情報（先頭アドレス）を保存している。

例）String name1 = "yamada"
    String name2 = "yamada"
それぞれの"yamada"は別のもの

- 文字列型
【String 変数名 = "文字列"】
文字列を格納できる。
int num = 30　→数字
String num ="30" →文字列

- 列挙型
【enum 変数名 = {データ１,データ２,....}】
関連のある定数群を一つのまとまりとして扱うユーザー定義の参照型

```java
//列挙型Weekを宣言
enum  Week = {sunday,monday,tuesday,wednesday,thursday,friday.saturday};

public static void main (String[] args) {
	System.out.println(Week.sunday);
}
//出力結果："sunday"
```
人感センサーモジュールをmicro:bitで使ってみた

人感センサーモジュールをmicro:bitで使ってみました。

# センサーについて

みんな大好き秋月電子で500円で販売されているセンサーを使ってみました。
	
> [焦電型赤外線（人感）センサーモジュール　ＳＢ４１２Ａ](https://akizukidenshi.com/catalog/g/gM-09002/ "人感センサーモジュール")
> レンズ付きの焦電型赤外線(人感)センサーモジュールです。とても小さく、狭いところにも設置することができます。検知出力保持時間の調整ができます。
> 
> ■主な仕様
> ・電源電圧：3.5V～12V
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71746/c1238058-5a42-221a-d79e-45dc93223522.png)


micro:bitの端子からは3.5Vは出ていませんがおそらく動くだろうと思いやってみました

# デジタル値を読み取るブロックでセンサーの値を調査
デジタル値を読み取るブロックでまずは調査。

結果は失敗。
全く反応がありません。

人がいない時 → 0
人がいる時 → 0

センサーに近づいても離れてもデジタル端子への入力は0という結果でした。

# アナログ値を読み取るブロックでセンサーの値を調査
続いてアナログ値

人がいない時 → 1または2
人がいる時 → 939

最大3Vで1024段階の刻みを見ているそうなので2.75V相当、なのですかね？

# 最終的なコード
500を閾値として人型とセンサー探知中的なアイコンが切り替わるようにしてみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71746/6a0258b3-101d-a13c-c1cc-72130b18c943.png)

<iframe width="560" height="315" src="https://www.youtube.com/embed/ZhWkA11n0fE" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
※指をセンサーから話しても5秒程度はセンサー自体が保持しています
しれっと登場したVPC Latticeって何者!? よく分からんから3行で頼む！

こいつを解説します。
凄そうな新機能ですが、AWS re:Invent 2022 2日目のキーノート終了後にしれっとアップされたのみで正体不明！

https://aws.amazon.com/jp/blogs/aws/introducing-vpc-lattice-simplify-networking-for-service-to-service-communication-preview/

# 一言で
VPC Lattice ＝ **「どこでもALB」** です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/f44aa233-9a60-30cd-7146-04ed0b3aadd6.png)

# 3行で
- 基本的には「ALBの集合体＋それらをまとめるハブ」みたいなもの。
- コンピュート系リソース同士をアプリケーション層で相互通信＆ルーティング＆アクセス制御できる。
- 複数のAWSアカウントやVPCから相互乗り入れできる。


# 解説
Latticeは「格子」という意味だそうです。
マイクロサービス間通信などの文脈で使われる「Mesh」に近い命名なのかも知れませんね。

上記のAWS News Blogを読み解き、ポンチ絵を描いてみました。
![lattice.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/ade61ba4-dcb5-fe77-226f-6d82bdb29d7a.jpeg)

### 仕組み
- HTTP/S、gRPCプロトコルで接続が提供される
- Latticeのコンポーネントとして「サービスネットワーク」の配下に「サービス」を作って使う
    - サービスネットワーク：複数のサービスを束ねるゲートウェイのようなもの
    - サービス：簡単に言うとELBのようなもの。以下の構成要素がある
        - リスナー
        - ルール
        - ターゲットグループ

### サービスネットワーク
- ここに紐づけられたVPCは、DNSでそのサービスネットワーク内のサービスを自動検出できるようになり、すべてのアプリケーション間通信がLattice経由になる
- Lattice経由で通信してよいAWSアカウント、VPC、アプリケーションをResource Access Managerで制御できる

### サービス
- ソフトウェアの機能の単位。独立してデプロイ可能なもの。
- 任意のアカウント or VPCに配置できる
- コンピュートリソースの組み合わせからなる（EC2、ECS、Lambda等）


### サービスの構成要素

#### リスナー（2つまで）
- 流入するトラフィックのポート＆プロトコルを定義する。
- 対応プロトコル：HTTP/S（1.1＆2）、gRPC

#### ルール
- 種別
    - デフォルトルール
    - （追加の）ルール
- 構成要素
    - 適用条件：ルールを適用するタイミングを定義
    - アクション：トラフィックをターゲットグループに転送する

#### ターゲットグループ
- 宛先となるコンピュートリソースの集まりのこと
- 指定可能なもの
    - EC2インスタンス
    - IPアドレス
    - Lambda関数
    - Kubernetes Pod（Gateway Controller for Kubernetes経由で指定可能）

### その他の機能

- アクセスポリシー：これをIAMリソースポリシーでサービスネットワークやサービスに紐づけることで、アクセス制御が可能。
- サービスディレクトリ：自アカウント＆紐づけ済みAWSアカウントに含まれるサービスをまとめて確認できる。

Latticeの利用者（管理者）として、ざっくり以下の2ロールを想定しているようです。
- ネットワーク管理者
    - サービスネットワークを作成し、全体のアクセス許可・監視を設定する
    - 他のAWSアカウントを紐づける
- サービスオーナー
    - サービスを作成し、固有のアクセス許可・監視を設定する
    - ルーティングを定義する（＝リスナー＆ルールの設定）
    - サービスをサービスネットワークに紐づける


# どういうときに使えるの？
今までなかった切り口の新機能なので、アイディア次第で色々ありそうです。

- 社内の複数システム間の通信をシンプルにまとめたい場合
    - これまではVPCピアリングやトランジットGWでVPC同士を繋ぎ、さらにその中でELB＋コンピュートリソースを配置したり、ルーティング設計したりアカウントまたぎでエンドポイント張ったり…とインフラレイヤーの対応がそこそこ大変でしたが、1アカウントにLatticeを配置し、各「アプリケーション」間の通信インフラをお手軽にまとめる（L7のルーティングだけを考える）ような使い方ができそうです。


# まとめ
現在Latticeはプライベートプレビュー中なのでまだサクッと触るのは難しいですが、公式ブログを読みながら手元で絵を描いてみるだけでもかなり理解が深まりました。
日々発表される抽象度の高いサービスは、こうやって理解してアウトプットしていこうと思いました。

今のところ、他に出ている貴重な日本語記事はクラメソさんのブログぐらいです。
こちらも大変勉強になるのでぜひご覧ください！

https://dev.classmethod.jp/articles/amazon-vpc-lattice/


# 2023/4/1 追記

とうとうGAしたので超速で触ってみました！

https://qiita.com/minorun365/items/260f6e1e29fcc61d1ad8
Wordpressでお問い合わせチャットボット

## まだ公開してないのですが、よさそうなのができました。

プラグインではなく、テーマとして実装

基本的に strpos で必要なワードを検索してるだけの非AI型

命を息吹きさせるのも楽しい感じです

## 案外小さなCSS (scss) とJavaScript (jquery) と php でできました。

比較的コンパクトな仕上がり

## 息吹きさせるのに大切なこと
アレクサで、以下のような事言えばわかりますが

・アレクサ　天才
・アレクサ　馬鹿

それなりのものが帰ってきますが
結論として、そういう雑談にも可能な限り対応できるように、手動でのディープランニングが必要になってしまいます。

できる限りヒトに近づけさせるか、キャラ制作担当者とも話し合ってます

## これ、MITで公開します

出来次第、よろしければお使いくださいとのことです。
画像をクリックしてファイルを選択して即時変更する


意外と参照できる記事がなかったので記述（基本的すぎて書いてないだけかも...）
通常の場合は```ファイルを選択する```ボタンを押して、submitボタンを押すことで変更が適用されます。
これを画像をクリックして、ファイルを開いたと同時に変更が適用されるようにしていきます。

# 求める挙動
画像をクリックしてファイルを選択して即時変更する

![qiita_file.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77737/84b7e8f9-8160-9f1f-a699-247fa0218072.gif)

# 実装手順
①「ファイルを選択」を押して、ファイルを選択して、submitを押せば画像が変更できるようになる
②画像をクリックして、ファイルを選択して、submitを押せば画像が変更できるようになる
③画像をクリックして、ファイルを選択して、submitを押さなくても変更が即時適用される


# 実装
### ①「ファイルを選択」を押して、ファイルを選択して、submitを押せば画像が変更できるようになる
**→active storageで画像の取得、表示をする**

active storageを使って画像の取得と表示をします。active storageについてはlink先のガイドの通りです。詳細は省きます。
https://railsguides.jp/active_storage_overview.html

モデルやコントローラのコーディングはlink先のガイドをみていただいて、ビューページに関しては以下のように記述すればファイルから画像を選択できます。
```
= form_with url: user_update_path, local: true do |f|　　
    = f.file_field :image　　　　　　　　　　　#imageという名前で画像取得
    - if @user.image.attached?   #画像が保存されているか確認
        = image_tag @user.image   #@user.imageで画像表示
    - else
        = image_tag "user_images/twittericon.jpeg"　　　#なければ適当な画像を表示
    = f.submit 　　　　　　　　　　　　　#submitを押すと画像をrecordに保存

```
とても簡単ですね。この段階では```ファイルを選択```が表示され、押すとファイルの選択ができ、```submit```を押すと変更が適用されます。

![スクリーンショット_-_11月30日_午後9_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77737/6dd0b91c-5449-65a1-4a55-637b112c9e52.png)

このままではスタイリッシュさに欠けるので```ファイルを選択```を非表示にします。

### ②画像をクリックして、ファイルを選択して、submitを押せば画像が変更できるようになる
**→1.```file_filed```に```display:none```を追加　 2.```file_field```と```image_tag```をlabelの下にネストする**

まず```file_field```のstyle属性に```display: none```を追記することで```ファイルを選択```の表示を消します。

そのままでは画像をクリックしても何も起きません。そこでlabelをつくり、その下に```file_field```と```image_tag```をネストさせます。そうすると```file_field``` ```image_tag```をひとかたまりで扱えます。
まとめると以下のようなコードになります。

```
= form_with url: user_update_path, local: true do |f|
    = f.label :image　　#<= 追記部分
        = f.file_field :image, style:"display:none;" #<= 追記部分
        - if @user.image.attached?
          = image_tag @user.image
        - else
          = image_tag "user_images/twittericon13.jpeg"
        = f.submit
```
ここまでで画像を選択して、ファイルを選択、submitを押せば変更が適用されるようになりました。
あとはsubmitを消すだけです

### ③画像をクリックして、ファイルを選択して、submitを押さなくても変更が即時適用される
**→イベント属性に```onchange: "submit(this.form)"```追加**

onchangeイベントを指定すると値が変化したときに実行されます。javascriptなど使っていれば馴染みがあるかもしれません。file_fieldにもイベントを指定できます。今回の場合はimageの中身が変わった時に変更が適用されるようにしたいです。
以下のようなコードになります。
```
= form_with url: user_update_path, local: true do |f|
    = f.label :image 
        = f.file_field :image, style:"display:none;", onchange: "submit(this.form)" #<= 追記部分
        - if @user.image.attached?
          = image_tag @user.image
        - else
          = image_tag "user_images/twittericon13.jpeg"
# submitは削除
```

ここまでで冒頭に挙げたような求める挙動になります。

他に使えるイベントについてはドキュメントを参照してください
https://railsdoc.com/form

# まとめ
* ```style: "display:none"```でファイル選択を非表示に
* ```onchange```がfile_fieldにもつかえる