OmniAICreator/Qiita-1.07M huggingface dataset:
【Rails】本番環境との画像参照の切り替え方について

#この記事について
デプロイを済ませたアプリを、ローカル環境で画像投稿するとなぜか全てNoImageになってしまう！

それの原因がわかったので記事にします。

おそらく、僕と同じで某プログラミングスクールを卒業した人は高確率でこの問題にぶつかっているんじゃないかな？と思っています。
なぜなら、カリキュラムに書いてある内容には、この問題について触れていないから（笑

##こんな感じ
全部NoImageになっちゃってるじゃん！！（汗

<img width="887" alt="スクリーンショット 2020-05-30 20.05.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593458/730217ce-cdbd-7208-c691-3388b17228a1.png">

#解決方法

`/config/initializers/carrierwave.rb`の記述で、本番とローカルで参照を分岐させる処理がなかったので追加して解決しました。

カリキュラムには`carrierwave.rb`というファイルを作成して、修正前のソースコードを記述しましょう。としか書かれていなかったんですね。
なので、ここでこのファイルが何をしているのか。をしっかり理解できていないと、コピペして満足してしまいます（笑

```修正前carrierwave.rb
require 'carrierwave/storage/abstract'
require 'carrierwave/storage/file'
require 'carrierwave/storage/fog'

CarrierWave.configure do |config|
    config.storage = :fog
    config.fog_provider = 'fog/aws'
    config.fog_credentials = {
      provider: 'AWS',
      aws_access_key_id: Rails.application.secrets.aws_access_key_id,
      aws_secret_access_key: Rails.application.secrets.aws_secret_access_key,
      region: 'ap-northeast-1'
    }
    config.fog_directory  = 'ここはアプリごとに異なる'
    config.asset_host = 'https://s3-ap-northeast-1.amazonaws.com/ここはアプリごとに異なる'
end
```

なので、`if Rails.env.production?`で本番かローカルかで参照する箇所を分岐させます。
本番だったらAWS、ローカルだったらstorageを:fileに。といった感じですね。

```修正後carrierwave.rb
require 'carrierwave/storage/abstract'
require 'carrierwave/storage/file'
require 'carrierwave/storage/fog'

CarrierWave.configure do |config|
  if Rails.env.production?
    config.storage = :fog
    config.fog_provider = 'fog/aws'
    config.fog_credentials = {
      provider: 'AWS',
      aws_access_key_id: Rails.application.secrets.aws_access_key_id,
      aws_secret_access_key: Rails.application.secrets.aws_secret_access_key,
      region: 'ap-northeast-1'
    }
    config.fog_directory  = 'ここはアプリごとに異なる'
    config.asset_host = 'https://s3-ap-northeast-1.amazonaws.com/ここはアプリごとに異なる'
  else
    config.storage :file
    config.enable_processing = false if Rails.env.test?
  end
end
```

これを記述して、再度`rails s`をし直しましょう！
じゃないと修正内容が反映されないのでお気をつけて！

**はい。反映されました！**

<img width="878" alt="スクリーンショット 2020-05-30 20.13.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593458/d5eafc75-64f6-15b2-ff1d-11775dc2370a.png">

#さいごに
理解している人からすれば「そりゃそうだ」っていう話ですが、やっぱり初学者はこういう当たり前の問題にぶつかりがちな気がします。
ですので、もし同じような事に悩まされている方がいて、この記事がお手伝いなったら嬉しいなぁ。と思っています。

それでは、ありがとうございました！
Eclipseショートカットと便利機能【備忘録】

# Eclipse 便利機能

- クラス、メッソドの宣言や実装場所にジャンプする機能
ctrlを押しながらクリック(F3キーでも代用可能)

- 呼び出し階層を開く機能
メソッド名を右クリック→参照
参照機能の上位版。
既存ソースコードを変更する際に影響範囲調査として使うときに便利。

- 参照機能
メソッド名を右クリック→参照

- デバッグ機能
Eclipseデバッグ時に変数の値を変更できる機能が便利。


# Eclipse ショートカット
- 補完機能：ctrl + space

- カーソルを文頭に移動：Home

- カーソル文末に移動:End

- カーソルがある行をそのまま下にコピー：ctrl + Alt + ↓

- 呼び出し元階層を開く：ctrl + Alt + h

- インデント調整：ctrl + Shift + f

- コメントアウト：ctrl + /

- javadocコメント：Alt + Shift + j

- インポート文自動宣言：ctrl + Shift + o
アプリケーションサーバーとwebサーバーの違い



詳しくは、下記サイトがとてもわかりやすかったです！
https://kitsune.blog/affiliate-build

#結論
rubyなど、動的な動きを実現させるために必要なのが
アプリケーションサーバー。

でも、大多数からのアクセスへの負荷には対応していいないため
webサーバーも必要になります。

###アプリケーションサーバー  
- Puma
- Unicon
など

###webサーバー  

- Nginx
- など
Linuxの誕生〜特徴をまとめてみた！

[Linux標準教科書](https://linuc.org/textbooks/linux/)を読んだので、まとめます！（知識の整理のため）
間違っている部分があったらごめんなさい＞＜

#1. ソフトウェアの種類
コンピュータは、ハードウェアとソフトウェアの大きく２つに分かれます。
ハードウェアとは、コンピュータの機械そのもの。
ソフトウェアとは、ハードウェア上で動作するプログラム。

ソフトウェアも、基本ソフトウェアと応用ソフトウェアと２つに分かれます。
基本ソフトウェアとはOperating System(OS)のことで、
応用ソフトウェアはその上で動くアプリケーションのことです。

WindowsやLinux、Mac OS Xは基本ソフトウェアであり、
WordやExcel、PowerPointは応用ソフトウェアです。

###▪ 基本ソフトウェアの役割
基本ソフトウェアは、応用ソフトウェアが動作するために必要な部品を提供します。
例えば、応用ソフトウェアにはウィンドウがあり、メニューやツールアイコン、
保存する際に出てくる確認メッセージなどがあります。
このような機能を応用ソフトウェアに持たせようとすると、作成が大変になります。
なので代わりに基本ソフトウェアが共通部品を提供する役割を担っています。

それ以外にも、「資源を管理する」という役割があります。
例えば、ワープロや表計算などのソフトウェアは同時に動かすことができます。
しかし、コンピュータは1つの処理しかできません。
これは基本ソフトウェアが、各ソフトウェアを高速で切り替えているから実現できます。

#2. Linuxとは
UNIXを元にして作られた、UNIX互換のOS。
1991年、当時フィンランドの大学生である「Linus Torvalds」によって作られました。
LinuxのプログラムはGPL(GNU General Public License: GNU 一般公衆利用許諾）という
ライセンス形式が採用されています。以下の特徴を含みます。

・プログラムを実行する自由
・ソースの改変の自由
・利用・再配布の自由
・改良したプログラムをリリースする権利

LinuxがGPLを採用したため、Linuxは多くのディストリビューター(※1)により開発され、
多くのユーザーに使われるようになりました。GPLを条件に受領したソフトウェアを一般に
頒布する場合、ソースコードを提供しなければいけません。しかし、このライセンス形式が
良いように働いた結果、Linuxは一部の個人や組織に独占されることなく、全利用者が
その恩恵を受けて発展させていくというスタイルができました。

※1：[コトバンク](https://kotobank.jp/word/%E3%83%87%E3%82%A3%E3%82%B9%E3%83%88%E3%83%AA%E3%83%93%E3%83%A5%E3%83%BC%E3%82%BF%E3%83%BC-6087)では以下のように説明されている。
>ディストリビューター
>>パソコンのソフトウェアやハードウェアの卸売りを専門に行う業者のこと。最近では、Linuxディストリビューションを配布する業者のことを指す言葉として使われることが多い。

#3. Linuxの特徴
基本ソフトウェアはさらに２つの領域に分かれます。
それらを「カーネル」と「ユーザランド」といいます。

###▪ カーネル
カーネルはオペレーティングシステムの中核となる部分で、ハードウェアと直接やりとり
するなど、中心的な機能を受け持つ部分。カーネルはハードウェアの違いを吸収して、
プログラムがどのハードウェア上でも同じように動作させる役割があります。

###▪️ ユーザランド
OSが動作するのに必要な、カーネル以外の部分のことです。
ファイルシステムやファイル操作コマンド、シェルなどの基本的なソフトウェア群を指します。

###▪️ シェル
「Linuxはコマンドで操作する」ことができます。コマンドとは文字通り「命令」のことです。
Linuxにはシェルと呼ばれる、対話型のコマンド入力環境が用意されています。
シェルには大きく2つの機能があります。
1つ目の機能は、入力されたコマンドを理解し、実行します。
2つ目の機能は、シェルスクリプトの実行にあります。
シェルスクリプトとは、「コマンドの入力を自動化する」ためのものです。1つのファイルに
コマンドを1行ずつ記述して作成します。作成したシェルスクリプトを実行することで、
コマンドの実行を自動化できます。

#4. ディストリビューション
###▪️ ディストリビューションの誕生
当初のLinuxはインストール作業が非常に困難で、一部のユーザーしか
使うことができませんでした。
Linuxディストリビューションとは、Linuxを使う上で必要なプログラムを
まとめ、簡単な手順で手軽にインストールできるようにすることです。
代表的なLinuxディストリビューターとして、Red HatやDebianProject、
Ubuntuを開発しているCanonicalなどがあり、さまざまな団体によって
「Linux」はリリースされ続けています。

###▪️ パッケージ
Linuxに対して追加機能を提供するもの。

###▪️ パッケージマネージャ
応用ソフトウェアの導入は、依存するソフトウェアやライブラリが
必要となる場合があります。
これらは正しい場所に、正しい順序でインストールしなくてはいけません。
パッケージマネージャは、パッケージを簡単にインストールしたり、
アップデートしてくれたりすることで、上記の役割を担ってくれます。
[WordPress] 検索結果の並び順

デフォルトの検索ウィンドウでサイト内検索した場合の記事の並び順。
3.7から関連順になってる。
https://wpdocs.osdn.jp/Version_3.7
検索の改善
より関連性のある検索結果となるよう改善
検索結果を表示するときの SQL

ORDER BY wp_posts.post_title LIKE '%検索してるテキスト%' DESC, wp_posts.post_date DESC
E資格の予想問題を作ってみる 数学編

来年のE資格に向けて予想問題集を作りました。

今回は機械学習編、分かっているのは

・出題範囲
・回答は選択式

の２つです。何か不備があるかもしれませんが復習がてらお使いください。
解答は白文字で記入しているので、文字を選択すれば見れます。

不備等があれば指摘してくださると幸いです。

深層学習はこちら
https://qiita.com/MeiByeleth/items/c9256c029852ab3a9487

機械学習はこちら
https://qiita.com/MeiByeleth/items/2fac526bbcab07ece4d7



#線形代数

##特異値分解

###1.

```math
A=
\begin{pmatrix}
2 & 0 \\
0 & 4
\end{pmatrix}
```
の固有値を求めよ。

(1)1,3
(2)0,2
(3)2,4
(4)-2,-4




解答:<font color="white">3</font>





###2.

```math
A=
\begin{pmatrix}
0 & 1 \\
2 & 0
\end{pmatrix}
```
を特異値分解せよ。

(1)

```math
{\begin{align}
A =
\begin{pmatrix}
0 & 1 \\
1 & 0
\end{pmatrix}
\begin{pmatrix}
2 & 0 \\
0 & 1
\end{pmatrix}
\begin{pmatrix}
1 & 0 \\
0 & 1
\end{pmatrix}\\
\end{align}
}
```

(2)

```math
{\begin{align}
A =
\begin{pmatrix}
0 & 1 \\
1 & 0
\end{pmatrix}
\begin{pmatrix}
4 & 0 \\
0 & 1
\end{pmatrix}
\begin{pmatrix}
1 & 0 \\
0 & 1
\end{pmatrix}\\
\end{align}
}
```


(3)

```math
{\begin{align}
A =
\begin{pmatrix}
1 & 0 \\
0 & 1
\end{pmatrix}
\begin{pmatrix}
2 & 0 \\
0 & 1
\end{pmatrix}
\begin{pmatrix}
0 & 1 \\
1 & 0
\end{pmatrix}\\
\end{align}
}
```


(4)


```math
{\begin{align}
A =
\begin{pmatrix}
1 & 0 \\
0 & 1
\end{pmatrix}
\begin{pmatrix}
4 & 0 \\
0 & 1
\end{pmatrix}
\begin{pmatrix}
0 & 1 \\
1 & 0
\end{pmatrix}\\
\end{align}
}
```



解答:<font color="white">1</font>







#確率・統計

##一般的な確率分布


###1.

ベルヌーイ分布はxとして0か1の2値をとり、xが1となる確率がμである分布である。つまり、
P(x=1)=μ
P(x=0)=1-μ
P(x=z)=（a）
(a)に当てはまる式はどれか。

(1)$μ^z(1-μ)^{(1-z)}$
(2)$(1-μ)^zμ^{(1-z)}$
(3)$μ^{(1-z)}(1-μ)^z$
(4)$μ^z(1-μ)^z$

解答:<font color="white">1</font>


###2.
ガウス分布の式を選べ。ただしσは分散、μは平均とする。

(1)$N(\mu,\sigma^2)=\frac{1}{\sqrt{2\pi \sigma ^2}} \exp \left( -\frac{(x-\mu)^2}{2\sigma ^2} \right)$
(2)$N(\mu,\sigma^2)=\frac{1}{\sqrt{2\pi }} \exp \left( -\frac{(x-\mu)^2}{2\sigma ^2} \right)$
(3)$N(\mu,\sigma^2)=\frac{1}{{2\pi \sigma ^2}} \exp \left( -\frac{(x-\mu)^2}{2\sigma} \right)$
(4)$N(\mu,\sigma^2)=\frac{1}{\sqrt{2\pi }} \exp \left( -\frac{(x-\mu)^2}{2\sigma } \right)$

解答:<font color="white">1</font>

###3.
ガウス分布の期待値はどれか


(1)$σ$
(2)$σ^2$
(3)$μ^2$
(4)$μ$

解答:<font color="white">4</font>


##ベイズ則


###1.

ジョーカーを抜いたトランプの山札がある。一枚カードをとるとそのカードのマークはハートであった。この時カードが絵札である確率は？



(1)$\frac{1}{13}$
(2)$\frac{4}{13}$
(3)$\frac{1}{4}$
(4)$\frac{1}{52}$

解答:<font color="white">2</font>


#情報理論



###1.

平均情報量の式を選べ


(1)$\sum_x P(x)logP(x)$
(2)$-\sum_x P(x)logP(x)$
(3)$-\sum_x logP(x)$
(4)$\sum_x P(x)$

解答:<font color="white">2</font>



###2.
自己情報量の式を選べ


(1)$P(x)logP(x)$
(2)$- P(x)logP(x)$
(3)$- logP(x)$
(4)$ P(x)$

解答:<font color="white">3</font>


###3.KLダイバージェンスがもととなっている手法を選べ


(1)Wavenet
(2)VMAP
(3)A3C
(4)GRU

解答:<font color="white">2</font>




参考文献

https://logics-of-blue.com/information-theory-basic/
Dockerについて

#前提
Dockerについて学んだことを書いていきます。

#本題

#基本コマンド
docker image build -t
Dockerfileの情報を元にコンテナのイメージをbuildする。

Build
↓
指定したディレクトリに存在するDockerfileを読み込みコンテナイメージをbuildする。
↓
buildしたコンテナイメージは実行したマシンに保存される。
保存する時の名前を-tのタグでつける。


ローカルに保存されているDockerコンテナの内容表示
docker image ls


docker run -d -p 8080:80 dockerdemo:latest
-d　デタッチ（コンテナをバックグランドで起動する）
-p パブリッシュ（ポートを指定、左側がホストからの接続ポート・右側がコンテナ側への接続ポート）
ホストへは８０８０のポートで接続するが、実際には８０ポートに変換されるイメージ。


実行中のコンテナの出力
docker container ls



コンテナの停止
docker container stop コンテナID



#コンテナのネットワークとは

サーバにはLANポートがある。
物理的にLANケーブルを接続するNICがいくつかある。
EC2などの仮想サーバも同様。
EC2はこのようなNICが仮想化されているだけで仕組みは物理サーバと同様。
Eth0にきた通信はKernelで制御される。
リナックスだとiptablesなどで通信の制御をしたりすることがある。
Dockerはこのようなカーネルレベルでもいい感じに動作し、コンテナと外部通信の橋渡しをしてくれる。

Eth0のような物理的なレイヤーを通過
↓
Dockerネットワークのレイヤーに到着
↓
Dockerデーモンが物理レイヤーとDockerレイヤーのネットワークを接続する
↓
コンテナはDockerデーモンを通じて外部のネットワークと通信している
↓Dockerレイヤーの中身
もっともよく使われているシンプルなネットワーキングBridge
↓
Bridgeという仮想的なネットワークの接続ポイントを使用した方法
↓
コンテナを3つ立ち上げた場合
↓
vethをかいして、それぞれのコンテナはBridgeに接続している
↓
Bridgeはネットワーク機器でいうとスイッチのような役割で、Bridge自体は独立したネットワーク領域
↓
Bridgeに応じたIPアドレスがコンテナに割り当てられる
↓
Bridgeは複数作成することができる


docker network ls
現在のDockerネットワークの情報を表示する。

docker network inspect bridge
ネットワークアドレスが何になるか確認。

Bridge作成
docker network create --attachable -d bridge --subnet=10.99.0.0/16 greenbridge



#コンテナのボリュームとは
デフォルトでは、コンテナの内部で生成されたデータはコンテナの内部に保存される。
→コンテナを削除してしまうと綺麗さっぱり消えてしまう。
コンテナは不変かつ一時的な実行プロセスという特徴の一つであり、諸刃の剣。
データベース系のコンテナはずっと消えることのないデータを必要としている。

コンテナの中にカスタマイズしたデータを保存しないようにする。

Dockerのmountを使用することでコンテナとホスト、両方ファイルを共有することができる。

ファイルを共有する領域がDockerの管理下にあるか、ホスト側の管理下にあるかの違い。

Volumes
コンテナとDockerエリアと連携する方法

Bind mount
任意のファイルシステムの領域とコンテナがファイルを共有できる


Dockerの管理下Volumesのmount方法
Dockerfileの編集
VOLUME /var/www/html
VOLUMEはコンテナ側のマウントポイントを指定する

Bind mountでファイル共有方法
docker container run --name bindmount1 -d -p 80:80 -v /root/bindmount:/var/www/html volumdemo:latest

-v
左側にホストでマウントさせたいディレクトリを指定する。
：を挟んで右側のコンテナ側のマウントさせたい領域



docker container run --name bindmount1 -d -p 80:80 -v ${pwd}:/var/www/html volumdemo:latest

${pwd}で現在いるディレクトリを自動的に置き換わる。
PowerShellでユーザ環境変数を設定する

# この記事は何？

PowerShell で環境変数を操作するとき、プロセス内限定であれば、PATHを例にすると `Get-Item env:PATH` や `Set-Item env:PATH "xxx"` や `$env:PATH += "value"` などで環境変数の操作ができる。

一方で、プロセスを終了後に、再度PowerShellを起動したときに有効になるような、マシンの環境変数や、ユーザの環境変数を変更する方法がある。

# 方法

```powershell
# なければ追加したいパス
$PathValue = "C:\tools\mdctags\bin"

# 環境変数を得る
$OldPathVar = [System.Environment]::GetEnvironmentVariable("PATH", "User")

# 環境変数に任意のパスを加える
$PathArray = $OldPathVar.Split(";")
if ($PathArray.IndexOf($PathValue) -eq -1) {
    $PathArray += $PathValue
}
$NewPathVar = $PathArray -join ';'
$NewPathVar

# 新しい環境変数を設定する
[System.Environment]::SetEnvironmentVariable("PATH", $NewPathVar, "User")
```

# 参考資料

* [GetEnvironmentVariable(String, EnvironmentVariableTarget)](https://docs.microsoft.com/ja-jp/dotnet/api/system.environment.getenvironmentvariable?view=netcore-3.1#System_Environment_GetEnvironmentVariable_System_String_System_EnvironmentVariableTarget_)
* [EnvironmentVariableTarget 列挙型](https://docs.microsoft.com/ja-jp/dotnet/api/system.environmentvariabletarget?view=netcore-3.1)
製造現場でよく見るCUM_plotがネットに落ちて無かったのでpythonで作ってみた

0.初めに
============
生産現場で不良解析をしていると、CUM_plotなるものをよく用いる。正規分布だと直線になり、外れ値や複数の正規分布が混じっているかなどが分かりやすい。ふとpythonで作成しようと思ったらどうしても図1のCUMが出てくるが、図2のCUMが出てこない。。。どうやら通常はCUMというと図1を示すよう。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448643/fa0e88af-bee5-180c-f961-29c5db987afb.png" width=50%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448643/b3ea7992-668e-ab61-eaad-5ad78e48fa86.png" width=50%>

という事で、図2のCUM作成にチャレンジしてみました。正しいか不明なので、誤り等あればご指摘いただけると助かります。
1.CUM plotとは？
============
累積分布関数(cumulative distribution)の略。ただしこれでググると図1しか出てこない。。。
https://ja.wikipedia.org/wiki/%E7%B4%AF%E7%A9%8D%E5%88%86%E5%B8%83%E9%96%A2%E6%95%B0
図1のCUMの作成方法は下記URL参照
https://matplotlib.org/3.1.1/gallery/statistics/histogram_cumulative.html
2.CUMの作り方
============
図2のCUMをよく見るとy軸が正規分布を写像しているように見える。ただしそんなスケールはmatplotlibにないので、無理やりスケール変換し割り当てて見ました。

```
#宣言
from scipy.stats import norm
import numpy as np
import matplotlib.pyplot as plt

#dataの作成
np.random.seed(19680803)
mu = 200
sigma = 3
x = np.random.normal(mu, sigma, size=100)

#累積分布関数の逆関数をxに割り当てる
norm_arr = list()
for no in range(1,len(x)+1):
   norm_arr.append(norm.ppf((no)/(len(x)+1))-norm.ppf(1/(len(x)+1)))
norm_arr=norm_arr/max(norm_arr)#正規化
x.sort()#xを小さい順にソート

#y軸表示の変更
scale =[]
list_axis =[0.0001,0.001,0.01,0.05,0.1,0.2,0.3,0.5,0.7,0.8,0.9,0.95,0.99,0.999,0.9999]
for no in list_axis:
   scale.append(norm.ppf(no)-norm.ppf(0.0001))
scale=scale/max(scale)

#描画
fig, ax = plt.subplots(figsize=(8, 4))
linestyles = '-'
ax.grid(True)
ax.legend(loc='right')
ax.set_title('Cumulative step histograms')
ax.set_xlabel('data')
ax.set_ylabel('Percentage')
plt.yticks(scale,list_axis)
ax.plot(x,norm_arr,label='linear',marker='o',markersize=1.0,linewidth=0.1,linestyle=linestyles)

plt.show()
```
実行すると上記図2がそのまま出力されます。
【rails】GoogleMapsAPI 緯度、経度が保存できない時の記述

# はじめに
以前書いた記事の追記でgooglemapAPIを使用した際に、住所は登録できているが緯度、経度が保存されないことでハマったので追記として残しておきます。

[【rails】google maps api　地図情報含んだ投稿をして表示させる方法](https://qiita.com/sho-17/items/0854d59d52d9c3679370)

# 実現したいこと
住所入力して投稿できてデータベースにも保存されているが、緯度、経度が保存されないことを解決させたい。


#geocoderについて

いろいろな記事を調べているとgeocoderは何も設定しないと精度があまり良くないことがあるそうです。
解決するためにはGoogle Map APIの情報源を使えるように設定すれば良いそうです。

#geocoder.rbファイルを作成

ではさっそく実装していきましょう。

configフォルダ内にgeocoder.rbファイルを作成します。

```:ターミナル
$ bin/rails g geocoder:config
```

上記の記述によりconfig/initializers/geocoder.rb  ファイルが作成されます。

作成されたファイルを編集していきます。

```ruby:geocoder.rb
Geocoder.configure(
  # Geocoding options
  # timeout: 3,                 # geocoding service timeout (secs)
   lookup: :google,         # name of geocoding service (symbol)
  # ip_lookup: :ipinfo_io,      # name of IP address geocoding service (symbol)
  # language: :en,              # ISO-639 language code
   use_https: true,           # use HTTPS for lookup requests? (if supported)
  # http_proxy: nil,            # HTTP proxy server (user:pass@host:port)
  # https_proxy: nil,           # HTTPS proxy server (user:pass@host:port)

#YOUR_API_KEYにはご自身のAPIキーを記述してください。
   api_key: YOUR_API_KEY,               # API key for geocoding service
  # cache: nil,                 # cache object (must respond to #[], #[]=, and #del)
  # cache_prefix: 'geocoder:',  # prefix (string) to use for all cache keys

  # Exceptions that should not be rescued by default
  # (if you want to implement custom error handling);
  # supports SocketError and Timeout::Error
  # always_raise: [],

  # Calculation options
  # units: :mi,                 # :km for kilometers or :mi for miles
  # distances: :linear          # :spherical or :linear
)
```

これでgeocoderの精度をあげてより詳細な場所を調べられるようになるそうです。


# 終わりに
以上で自分の問題は解決できました！
他にも記述ミスや処理が抜けている事が原因として考えられる可能性がありますが参考になれば嬉しいです！
Lambdaでwebhookをとりあえず受け取れているかを確認するための関数を作ってみた

# 動機
先日M5STICKCを使ってLINE Beaconを試してみた際に、
Webhook先を今まで使ったことないGASにしてみたところ、
どこでハマってしまっているのかよくわからない状態になってしまった。

知らない機能同士をまとめてためしたのが原因なので、Webhook先は毎回固定にしておいた方がいいのかもしれない

# 作ってみたもの
ということで、作ってみたのが個人的にWebhook先として汎用的に使える環境。

環境は一番慣れ親しんだものとしてAWSのLambda（とAPI Gateway）とする。

Lambda関数の中身は以下で、POSTで受けてもGETで受けてもログに出力できるようにする。

```python
import json

def lambda_handler(event, context):
    # 引数：eventの内容を表示
    print("Received event: " + json.dumps(event))
    # rawQueryString
    rawQueryString = event['rawQueryString']
    if(len(rawQueryString) != 0):
        queryStringParameters = event['queryStringParameters']
        print(queryStringParameters)
    
    # body
    body = event.get('body')
    if(not body is None):
        json_body = json.dumps(body)
        print(json_body)

    return {
        'isBase64Encoded': False,
        'statusCode': 200,
        'headers': {},
        'body': json.dumps('Hello from Lambda!')
    }
```

+ API Gatewayの作成については割愛。久々に作ってみたら前とかなり雰囲気が違っていてかなり戸惑った。
jQuery~中級編~

# プログラミングの勉強日記
2020年5月30日　Progate Lv.73

#####jQueryの読み込み
　ライブラリはインターネット経由で読み込むのが一般的。

```html:jQueryの読み込み
<head>
  <script src="https;//...jquery.min.js"></script>
</head>
```

#####jQueryファイルの読み込み
　jQueryは.js形式のファイルコードを書く。HTMLファイルで`<script srx="ファイルのURL"></script>`と書くことで、jQueryのコードを記述するファイルが読み込まれる。<font color=blue>headタグのなかでも書くことはできるが、`</body>`の直前に書くことで、WEBページの表示速度を速められる。</font>

```html
<body>
 ....
 <script src="script.js"></script>
</body>
```
#####jQueryの型
　jQueryはHTMLの中身を操作するので、HTMLの読み込みが完了してからjQueryによる操作を開始する。そのためにreadyイベントを用意して、`$(document).ready()`の中身にjQueryの処理を書く。この構文には省略形もあり、`$(function(){ });`と書く。

```js:Queryの基本的な形
$(document).ready(function(){
  //jQueryをかく。
});
```

```js:Queryの省略形
$function(){
  //jQueryをかく。
});
```
#####モーダルの表示
　モーダルとはclickイベントなどに基づいて表示/非表示が行われる要素のこと。

1.モーダルをCSSで非表示にする。
   `.login-modal-wrapper{ display:none; }`
2.ログインボタンにclickイベントを設定
   ` $('#login-show').click(function(){ });`
3.clickイベントでモーダルを表示

```js
$('#login-show').click(function(){ 
  $('#login-modal').fadeIn();
});
```

#####モーダルの非表示
　閉じるボタンをクリックしたときにモーダルが閉じるようにする。

1.閉じるボタンにclickイベントを設定
   `$('.close-modal').click(function(){ });`

2.fadeOutメソッドでモーダルを隠す

```js

$('.close-modal').click(function(){ 
  $('#login-modal').fadeOut();
});
```
　2つのモーダルを隠す場合には2つのモーダルの閉じるボタンに共通のclass名を指定し、クリックしたときにログインと新規登録のモーダルとともに隠す。

#####hoverイベントの準備
　1.hoverイベントを設定したい箇所にクラス名を指定

```html:各言語に対してlesson-hoverを追加
<div class="lesson lesson-hover"> </div>
```

　2.クラスに対してhoverイベントを設定

```js

$('.lesson-hover').hover{
  function(){
    //マウスを使ったときの処理
  },
  function(){
    //マウスが外れたときの処理
  }
};
```

#####hover機能
　hover時にtext-activeというクラスがあればレッスンの説明を表示させる。

1.CSSでtext-activeに`display:block;`を指定
2.マウスがのったとに説明文にtext-activeをつける
3.マウスが外れたときにtext-activeクラスを外す（非表示にする）

```css:text-activeがついていないとき
.text-contents{
  ...
  display:none; /*デフォルトではdisplay:none;で隠す*/
}
```
 
```css:text-activeがついているとき
.text-active{
  display:block; /*.text-activeがついているときは表示する*/
}
```

#####addClassメソッド
　指定した要素にクラスを追加できる。

HTML：`<p class="text-contents">...</p>`
jQuery：`$('.text-contents').addClass('text-active');`
text-contentsクラスのついた要素にtext-activeというクラスを追加する。
<font color=blue>このときのクラス名の前にドットは不要</font>

#####removeClassメソッド
　指定した要素から指定したクラスを取り除ける。

HTML：`<p class="text-contents text-active">...</p>`
jQuery：`$('.text-contents').removeClass('text-active');`
<font color=blue>このときのクラス名の前にドットは不要</font>
Gmailでメインの未読メールを検索する方法

Gmailでメインの未読メールを検索する方法
Gmailの検索フォームに下の条件を入れると検索できる。

````
is:unread ,category:primary 
````



**条件の説明**

- is:unread　・・・　未読メールを検索
- category:primary ・・・　メインのメールを検索


  
**参考画像**
<img width="1051" alt="4a4e49e18013709eb08189ed22e65e00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605055/d945b226-e042-bde7-be3f-08cd0f9d0720.png">
Nuxt.jsとFirebaseで個人開発アプリをシェアできるウェブサービスを作った話

# はじめに
4月で2年目になったウェブエンジニアです。普段はFEとBEを3:7くらいの割合でコードを書いています。
1年目は仕事で使っている技術やノウハウを学ぶことで精一杯でしたが、最近は仕事をこなしていく中で興味を持った技術について勉強する余裕が出てきました。
そこで、1年間ウェブエンジニアとして仕事をし、学んだ知識を生かして自分で１からウェブサービスを作ってみようと思い立ちました。
この記事では、備忘録という意味合いを兼ねつつ、なぜ、どのようにして、どんなものを作ったのかを書いていこうと思います。

# 作ったサービス
[アプリガーデン](https://appgarden.jp)という個人開発アプリをシェアできるサービスを作りました。
Twitter、Google、Githubのいずれかのアカウントがあれば簡単にユーザー登録ができ、アプリを投稿することができます。
また、ユーザー登録をせずに他の方々が作ったアプリを見るだけということも可能です。
<img width="800" alt="スクリーンショット 2020-05-28 20.24.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645419/b04eb7e5-dee2-a812-19b9-8626b9abaf79.png">

昨今、プログラミングへの関心が高まり、学びやすい環境になり個人でアプリケーションを開発するハードルが下がったと感じています。
アプリが完成したら公開してできるだけ多くの人に使ってほしいと思うのがエンジニアの性ですが、宣伝という壁が立ちはだかります。
法人であれば広告を出稿したりプレス掲載したりという方法を取ることができますが個人で行うとなると難しいのではないかと思います。
そんな個人開発エンジニアの方々が気軽に、簡単に作ったアプリをシェアできる場を作りたいなと思ったのがアプリガーデンを開発したきっかけです。
アプリをシェアすることはもちろん、ユーザー登録をせずにアプリを見るだけということも可能で、他のエンジニアが作ったアプリを見てモチベーションをもらうという使い方もできます。

# システムアーキテクチャ
![architecture.001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645419/015e1d12-a739-e5c4-06b9-c20283f37a71.png)

フロントエンドにNuxt.js、バックエンドにFirebase、CI/CDにはGitHub Actionsを利用しています。
UIフレームワークにはVuetifyを採用しています。コンポーネントが豊富で日本語のドキュメントが充実しているのでとても使いやすいです。
バックエンドはできるだけコードを書く量を減らしたかったので全てFirebaseでまかなっています。ウェブコンソールで1つプロジェクトを作ることで様々なプラットフォームを利用できるので管理も楽になります。
今回はSNS認証のためにAuthentication、アプリ情報やユーザー情報を保存するためにFirestore、ウェブサイトとして公開するためにHostingを利用しています。独自ドメインへの接続も含めて全て無料プランで利用することができます。

[Firebase Authentication](https://firebase.google.com/docs/auth?hl=ja)
[Firebase Firestore](https://firebase.google.com/docs/firestore?hl=ja)
[Firebase Hosting](https://firebase.google.com/docs/hosting?hl=ja)

Firebase HostingへのデプロイはGitHub Actionsで自動化しています。
releaseブランチへのコミットがトリガーとなりビルドからデプロイまで自動で行われるようにしています。

[GitHub Actions](https://github.co.jp/features/actions)

# おわりに
実装期間は主に土日に作業をして１ヶ月ほどでした。
Firebaseのおかげでバックエンドはウェブコンソールからぽちぽちするだけで環境を作ることができるので楽をすることができました。
今のところ最低限の機能しか実装できていないのでより使いやすくなるように拡張をしていきたいと思います。
Node.js インストールからREPL、ファイル実行まで(mac)

#インストール
[nodejs](https://nodejs.org/ja/)
nodejsのサイトでDLしちゃいましょう。
ターミナルでやる方法もありますが、別でググって下さい。

```
% node -v
v13.8.0
```

インストールできたらターミナルで確認。npmも一緒にインストールされます。
npmはpythonでいうpipです。

```
 npm -v
6.14.5
```

---
#Nodejs REPL

```
$ node
> 
> 3 + 2 
6
>
```

nodeシェルをうまく使うと開発にも役立ちます。
##便利なREPLコマンド
```
.break セッション内でブロックから抜け出す
.clear セッション内でブロックから抜け出す
.editor 複数行のコードを書ける
.exit セッション終了
.help ヒントの表示
.load ローカルなファイルにアクセスする
.save セッションのコードをファイルに保存する
```

---
#Node.jsでファイルを実行する

nodeの後にファイル名を指定することでJavascriptファイルをNode.jsで実行します

`main.js`

```
let message = "Hi, This is Node.js.";
console.log(message);
```

terminalで実行

```
% node main.js
> Hi, This is Node.js.
```

こんな感じです。
Tridactylで設定ファイルを作りたい

[Vimperator](http://vimperator.org/) の代替として名前が挙げられるも、果たして本邦でどのくらい使われているのか怪しい [Tridactyl](https://addons.mozilla.org/ja/firefox/addon/tridactyl-vim/) ですが、 設定ファイルを作ることができます。ただ、手順が少し面倒だったのでメモしておきます。

# 前提
- macOS 10.15
  - **OS によって手順が異なる可能性があります**
- Firefox 76.0.1
- Tridactyl 1.18.1

# 手順
## 1. Native Messengerをインストールする

Tridactyl のコマンドラインに `:nativeinstall` を入力します。

すると、以下のように表示されます。

>Installation command copied to clipboard. 
Please paste and run it in your shell to install the native messenger.
>
>**【日本語訳】**
インストールコマンドがクリップボードにコピーされました。
Native Messenger をインストールするには、シェルに貼り付けて実行してください。

指示されたとおり、シェルに貼り付けて実行します。

```
$ curl -fsSl https://raw.githubusercontent.com/tridactyl/tridactyl/master/native/install.sh -o /tmp/trinativeinstall.sh && bash /tmp/trinativeinstall.sh master
Installing manifest here: /Users/*****/Library/Application Support/Mozilla/NativeMessagingHosts/
Installing script here: XDG_DATA_HOME: /Users/*****/.local/share/tridactyl

Successfully installed Tridactyl native messenger!
Run ':native' in Firefox to check.
```

Tridactyl のコマンドラインに `:native` を入力し、正常にインストールされたことを確認します。

```
Native messenger is correctly installed, version 0.1.11
```

## 2. 設定ファイルを作成する

設定ファイルのパスについては、 `:help source` には以下のように記載されています。

> If no argument given, it will try to open ~/.tridactylrc, ~/.config/tridactyl/tridactylrc or $XDG_CONFIG_HOME/tridactyl/tridactylrc in reverse order. You may use a _ in place of a leading . if you wish, e.g, if you use Windows.

> **【日本語訳】**
 （source コマンドに）引数が与えられなかった場合、（source コマンドは） ~/.tridactylrc 、 ~/.config/tridactyl/tridactylrc 、 $XDG_CONFIG_HOME/tridactyl/tridactylrc を逆順に開こうとします。また、例えば Windows を使っている場合のように、お望みならば、先頭の . の代わりに _ を使うこともできます。

今回は、 `~/.tridactylrc` を作成します。
`YY` を押したときに、ページのタイトルと URL をヤンクする設定を追加します。[^1]

[^1]: もともと、これがやりたくて調べていました。Twitter でシェアするときに、毎回、ページタイトルを手動でコピーするのが面倒だったので... JavaScriptのコードを書き換えれば、マークダウン形式も作れるでしょう。右クリックでコピーできるアドオンを昔使っていたのですが、右クリックさえも煩わしい（笑）

```
bind YY composite js document.title + "\n" + document.URL | yank
```

- `bind キー コマンド`
  - キーにコマンドを紐付けます（キーを押したらコマンドが実行されるようにする）
- `composite コマンド1 | コマンド2`
  - パイプを実現します。コマンド1の戻り値が、コマンド2の標準入力になります
- `js JavaScript`
  - JavaScript を実行します
- `yank`
  - ヤンクです

## 3. 設定ファイルを読み込む

Tridactyl のコマンドラインに `:source` を入力します。[^2]

[^2]: `:source ~/.tridactylrc` としても問題ないと思います。

適当なページで `YY` を押し、クリップボードにコピーされているかを確認します。例えば、Qiita のトップページならば、このようになります。

```
Qiita
https://qiita.com/
```

# 参考
- Tridactyl Wiki
  - [Exemplar .tridactylrc files](https://github.com/tridactyl/tridactyl/wiki/Exemplar-.tridactylrc-files)
  
- [Tridactylのnative messengerを入れた - クマーなひとときv2](https://tonkuma.hatenablog.com/entry/2018/11/23/153703)
  - Native Messenger について詳しい[^3]

[^3]: 「WebExtensions のことはよく分からないので割愛した」とか言えない。
Unityでマウスの位置に画像(guiのimage)を表示させる

#Unityでマウスの位置に画像(guiのimage)を表示させる

###guiのimageを使ってマウスポインターの代わりに画像を表示させる
画像からアニメーションにも応用できるはず

###用意するもの
・Windows PC
・Unity (制作時に使用したバージョンは2019)
・マウスの位置に表示させたい画像

###作りたいもの

![Rec_20181224_181408_20200530_175000.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243269/9e3acfb3-0645-e7e2-0fec-41e8e5a41acb.gif)
黒い丸がマウスポインタ—に追従している。
これはわかりやすくするためにマウスポインターを表示している。

###作りたかた
1.HierarchyのプラスボタンからUI > ImageからCanvasとImageオブジェクトを作る。
2.Imageに入れる画像をTexture TypeをSprite(2D and UI)にし、ImageのSource Imageに入れる。
3.Imageのオブジェクト名を「MouseImage」に変更する。
4.HierarchyのプラスボタンからCreate Emptyで空のオブジェクトを作る、オブジェクト名を「MouseManager」に変更する。
5.下記のスクリプトをC#のファイルで作り、MouseManagerオブジェクトに入れる。
完成

![image.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243269/3cb28f52-9312-73d5-9e95-c5d4470553d2.png)
![manager.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243269/2f965065-7325-dec3-138d-bd21ed42b715.png)




###スクリプト
``` C#:MousePointerpos.C#

    //画像
    public Image Mouse_Image;
    //Canvasの変数
    public Canvas canvas;
    //キャンバス内のレクトトランスフォーム
    public RectTransform canvasRect;
    //マウスの位置の最終的な格納先
    public Vector2 MousePos;

    // Start is called before the first frame update
    void Start()
    {
        //マウスポインター非表示
        Cursor.visible = false;

        //HierarchyにあるCanvasオブジェクトを探してcanvasに入れいる
        canvas = GameObject.Find("Canvas").GetComponent<Canvas>();

        //canvas内にあるRectTransformをcanvasRectに入れる
        canvasRect = canvas.GetComponent<RectTransform>();

        //Canvas内にあるMouseImageを探してMouse_Imageに入れる
        Mouse_Image = GameObject.Find("MouseImage").GetComponent<Image>();
    }

    // Update is called once per frame
    void Update()
    {
        /*
         * CanvasのRectTransform内にあるマウスの位置をRectTransformのローカルポジションに変換する
         * canvas.worldCameraはカメラ
         * 出力先はMousePos
         */
        RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRect,
                Input.mousePosition, canvas.worldCamera, out MousePos);

        /*
         * Mouse_Imageを表示する位置にMousePosを使う
         */
        Mouse_Image.GetComponent<RectTransform>().anchoredPosition
             = new Vector2(MousePos.x, MousePos.y);
    }
```


##参考文献
ぐーるらいふ 遊びのunityのメモ帳。敗北者の末路。
【Unity】タッチした位置にuGUI(RectTransform)を表示する
https://ghoul-life.hatenablog.com/entry/2018/11/13/000955
2020年5月30日閲覧

Unity DOCUMENTATION
RectTransformUtility .ScreenPointToLocalPointInRectangle
https://docs.unity3d.com/ScriptReference/RectTransformUtility.ScreenPointToLocalPointInRectangle.html
2020年5月30日閲覧
zsh上でhistoryコマンドを打つと直近15件しかでてこない

# 概要

bashを使ってたときは、`history`で全履歴が表示されたのに対して、
zshでは`history`を叩いても、直近15件しか表示されなくて困ってました。

# 原因

bashの`history`とzshの`history`コマンドでは仕様が違う。
両方ともfcコマンドのaliasとして用意されているみたいですけど、aliasのはられ方が違うのかも。詳細は調べていないので、知っている方いたら教えて下さい。

# デフォを全件表示にする

```zsh
alias history='history 1'
```

`history 1`で1~現在までの履歴が表示されるので、`history`にaliasを貼る。


# 参考
- [bash内部コマンド history, fc - Qiita](https://qiita.com/ririn_yume/items/526df6fa50b8c32ff5f6)
- [zsh の fc ビルトインコマンド - Please Sleep](https://please-sleep.cou929.nu/zsh-builtin-command-fc.html)
Bashのキャッシュでハマった話

こんにちは，yourilです．
タイトルの通りBashのキャッシュでハマったので，備忘録として残します．

# TL;DR

コマンドを入れ直したりしてパスが変わると，Bashは以前実行したコマンドのパスをキャッシュするため，古いパスを参照して「コマンドが見つからない」と怒られることがある．
その場合，以下2つのコマンドでBashのキャッシュの確認，削除ができるので，キャッシュが原因でないか確認してみる(そもそもパスが通ってない等はまた別問題)．

- Bashのキャッシュを確認

```bash
$ hash
```
- Bashのキャッシュを削除

```bash
$ hash -r
```
以下は自分がハマった経緯なので，興味のある方だけどうぞ．

# 何があったか

ansibleで遊んでいたところ，使っているpythonのバージョンが2系のままだったので，入れ直して3系にすることにしました．
古いバージョンの削除，新しいバージョンのインストールまでは成功したものの，バージョンを確認しようとしたところ...

```bash
$ ansible-playbook --version
-bash: /usr/bin/ansible-playbook: そのようなファイルやディレクトリはありません
```
???
ファイルが存在しない...
なお，ansible本体のバージョンを確認してみると

```bash
$ ansible --version
ansible 2.9.7
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/vagrant/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.6/site-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 3.6.8 (default, Apr  2 2020, 13:34:55) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
```

実行できる．
各コマンドのパスを確認してみると

```bash
$ which ansible
/usr/local/bin/ansible
$ which ansible-playbook
/usr/local/bin/ansible-playbook
```
同じパスにあるのに，`ansible`は実行できて`ansible-playbook`は別のパスを参照して実行できない...
この時点で自分はキャッシュの存在に気付いておらず，「パスの優先順位の問題か？でもコマンド毎に変わるのはおかしいのでは？」等，かなり迷走しました．

その後，あるサイトで見た状況が上記とほぼ同じだったため，試しにキャッシュを確認したところ，

```bash
$ hash
hits    command
   5    /usr/local/bin/ansible
  25    /usr/bin/ansible-playbook
...
```

`ansible`は`/usr/local/bin`，`ansible-playbook`は`/usr/bin`としてキャッシュされており，異なるパスを参照していることが分かりました．
キャッシュを`hash -r`で削除し，再度コマンドを確認すると，

```bash
$ ansible-playbook --version
ansible-playbook 2.9.7
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/vagrant/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.6/site-packages/ansible
  executable location = /usr/local/bin/ansible-playbook
  python version = 3.6.8 (default, Apr  2 2020, 13:34:55) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
```

無事に実行できました．

# まとめ

結果的にはいくつかのサイトを見て回ってキャッシュが原因ということが分かったものの，こういう機会でもないと全く意識しない上にすぐ忘れそうだなと思い，簡単にまとめました．
コマンドは同じものをよく実行するため，言われてみればキャッシュを活かしやすいなとは思いつつ，ハマると厄介だということも再認識しました(個人的に，ブラウザ等のキャッシュにもよくハマる)．

最後まで読んで頂きありがとうございました．
AZ-103の合格までに行ったこと

# はじめに
普段業務でAzureを使用しているので、一度体系的に学習しようとAZ-103の取得を決めました。2020/05/30に無事合格することができましたが、AWSと比べて勉強方法などの情報が少ないと感じたため、合格するまでに行ったことをまとめました。

# AZ-103について
AZ-103はMicrosoftの認定資格である**Azure Administrator Associate**を取得するために合格する必要のある試験です。新試験であるAZ-104も受験可能ですが2020年8月末までは受験可能なので、情報の比較的多いこちらの試験を受験したほうがいいかもしれません。AZ-104の詳細は[こちら](https://docs.microsoft.com/ja-jp/learn/certifications/exams/az-104#certification-exams)に示されています。

# 試験範囲
かなり抽象的ですが[公式ドキュメント](https://docs.microsoft.com/ja-jp/learn/certifications/exams/az-103)に試験範囲が示されています。試験問題の詳細は言えませが、受験した感触としては"IDの管理"の範囲が一番難しいと思いました。Active Directory周りは中々試すことも難しいので、実務での経験が無いと苦労すると思います。

# 勉強方法

行ったことを列挙したいと思います。

- [Microsoft Learn](https://docs.microsoft.com/ja-jp/learn/)
  
Microsoft公式の無料学習サイトで、実際にAzureを動かしながら学ぶことができるので導入として最適だと思います。量が膨大なので[こちら](https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RWtY7Z)のラーニングパスに則って学習することをお勧めします。しかし、基本的なところしか学習できないのでこれだけで試験に合格するのは厳しいと思います。

- Udemyの試験対策講座

オンライン学習サイトのUdemyの[az-103対策講座](https://www.udemy.com/course/70533-azure/)を購入しました。試験範囲を網羅していることに加え、試験範囲がアップデートされるごとに講座もアップデートされるのでとてもお得だと思います。Udemyは頻繁にセールを実施しているので、定価で買わずに安くなったタイミングで買いましょう！
講義が全て英語であるということだけがマイナスポイントです。

- whizlabsの模擬試験

whizlabsというUdemyに似たサービスで提供されている[模擬試験](https://www.whizlabs.com/learn/course/microsoft-azure-az-103)を購入しました。かなり本番に近い内容の問題が揃っているのでお勧めです。特に便利だったのは各問題の解説に関連する公式ドキュメントへのリンクが書いてあることです。公式ドキュメントは量が多すぎて見切れませんが、わからなかった部分だけ見ていけば効率的に理解が深まると思います。whizlabsでも試験対策講座が提供されているようですが購入はしていないので詳細はわかりません（こちらも英語です）。whizlabsもセールをやっていたりします。

- 実際にAzureを触る

自分の場合は会社から検証用のアカウントを与えてもらっていたので実際にいろいろなリソースを作成してみてました。Microsoft Learnや対策講座では触れられないような細かいところが聞かれたりするので、実際に触ってみて覚えていくのも大事だと思います。動画で学ぶよりも自分で手を動かした方が記憶に残りますしね。そんなアカウントもらえないという方でもAzureの無料枠を使ったりして、少しでも触ると合格率が上がる気がします。

# 受験に関して

試験は700/1000点が合格ラインで試験時間は180分です。時間は十分すぎるほど余裕があるので気にしなくて大丈夫です（自分は50分弱で終わりました）。試験結果は終了後すぐにわかります。
テストセンターで受験する場合は身分証明書が2点（自分は免許証と保険証にしました）必要なので忘れないように気をつけてください。詳しくは試験を予約した際のメールにリンクが書いてあるので確認しましょう！

# おわりに

次はとりあえずAWSのSAAでも取ろうかと思っていますが、Azureの資格は次どれを取ろうか悩み中です。笑
難易度的にはAZ-300、AZ-301あたりになるんですかね？
[Swift]Eurekaのリスト選択に独自のViewControllerを利用する


背景
---
先日、[ScoreBox](https://apps.apple.com/jp/app/scorebox/id1489805521)という麻雀成績管理アプリを個人開発してリリースしました。
その中の設定画面では[Eureka](https://github.com/xmartlabs/Eureka)を使用しています。
Eurekaは非常にお手軽に設定画面を作成できるのでおすすめです。

悩んだ
---
麻雀というからには4人（または3人）のプレイヤー選択が必要です。
Eurekaでは決まったリストからのマルチ選択機能は標準で用意されていましたが、
今回はリスト表示後も選択できるプレイヤー数をその場で増減させたかったので工夫が必要でした。

工夫した
---
だったら自分でプレイヤー選択のViewControllerを自作し、
Eurekaから呼び出そうということでやったのがこちら。
呼び出し先のViewControllerの内容は割愛していますが、Controller内でプレイヤーリストの編集が可能になっています。

```swift
<<< ButtonRow() {
    $0.title = "\(game.playerList.count)人 選択中"
    $0.hidden = false
    $0.presentationMode = .show(controllerProvider: ControllerProvider<UIViewController>.callback {
            return playerListVC
        },
        onDismiss: { vc in
            vc.navigationController?.popViewController(animated: true)
        })
    }
    .cellSetup{ (cell, row) in
        cell.imageView?.image = UIImage("アイコン画像")
    }
    .cellUpdate({ (cell, row) in
        cell.textLabel?.text = "\(game.playerList.count)人 選択中"
    })
```


実際の画面
---
![20200530_173042.GIF](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530745/de5bc2cd-43cd-24d0-7810-f36bd099df24.gif)

ポイント
---
```
$0.presentationMode = .show(controllerProvider: ControllerProvider<UIViewController>.callback {
    return playerListVC
},
onDismiss: { vc in
    vc.navigationController?.popViewController(animated: true)
})
```
EurekaのButtonRowがタップされた際に表示する自作のViewControllerを指定し、

```
.cellUpdate({ (cell, row) in
    cell.textLabel?.text = "\(game.playerList.count)人 選択中"
})
```

自作のViewControllerから戻ってきた場合にButtonRowのキャプションを更新しています。

今後も開発中に工夫した点を残していきたいと思います。（需要が分からないので主に自分への備忘）
TDPC G 辞書順

##問題
https://atcoder.jp/contests/tdpc/tasks/tdpc_lexicographical
##見た感じ
文字列についてのdpで解くんやろなと思いながら、|s|<=1000000とでかいので、どうしようかと。
最後に辞書順k番目の部分文字列を再現しないといけないので、以下のようにdpテーブルを定めた。

```math
dp[c][i]=文字cで始まるsのi文字目以降で作れる部分文字列の個数\\
nxt[c][i]=sのi文字目以降で文字cが出てくる最小のindex\\
dp[c][i]=\begin{cases}
dp[c][i+1]~~~(c\neq s[i])\\
1+\sum_{j}dp[j][i+1]~~~(c=s[i])
\end{cases}\\
nxt[c][i]=\begin{cases}
nxt[c][i+1]~~(c\neq s[i])\\
i~~(c=s[i])
\end{cases}
```
このようにdptableを定めれば求める文字列の1文字目ans[0]は、
$ans[0]=\min_{c}(c~|\sum_{i=0}^{c}dp[i][now=0]>=k)$で計算でき、kを$k=k-\sum_{i=0}^{ans[0]}dp[i][now]-1,~now=nxt[ans[0]][now]+1$として、kがゼロになるまでこれを繰り返せば、ansが求める文字列になる。
と思って実装すると、まずメモリが足りない。
ここで、nxt[c][i]とdp[c][i]の更新式が似ているので、nxt[c][i]をdo[c][i]で代用できることに気づいた。つまり、$nxt[c][i]=\min_{j}\{j~|dp[c][i]!=dp[c][j]\}$となっている。
これを改善して出すと、またwaが出る、よく見ると、dptableの各要素がでかくなりすぎてるようだ。
ここで、ansの復元の式（プログラム）を見ると、kは高々10^18なので、dp[i][now]が10^18+1より大きければ復元結果に影響はないことがわかる。さらに言えば、dp[i][now]がk+1より大きいときはk+1にしておけば問題ない。
また、nxtの復元のためにdp[c][i]はiが大きくなるにつれて多少大きくなる必要があるので、dp[i][now]がk+1より大きいときは、dp[i][now]=k+nowにしておくことにする。
##解法
上の漸化式を計算して、dptableを埋めながら、dp[c][i]がk+1より大きくなるところは、k+iを代入しておく、あとは上の復元式に従って、求める解を復元していく
##ソースコード
```c++
const int N_MAX=1000010;
string s;
ll k,dp[26][N_MAX];


string solve(){
    int n=s.size();
    vrep(i,n){
        int c=s[i]-'a';
        rep(j,26){
            if(j==c){
                rep(l,26){
                    dp[c][i]+=dp[l][i+1];
                    if(dp[c][i]>k+1)dp[c][i]=k+i;
                }
                dp[c][i]+=1;
            }else{
                dp[j][i]=dp[j][i+1];
            }
        }
    }
    
    int now=0,c;
    ll count;
    string res="";
    while(k){
        count=1;
        for(c=0;c<26;c++){
            if(count+dp[c][now]>k)break;
            count+=dp[c][now];
        }
        if(c==26)return "Eel";
        res+=('a'+c);
        k-=count;
        rep1(i,n-now+1){
            if(dp[c][now+i]!=dp[c][now]){
                now=now+i;
                break;
            }
        }
    }
    return res;
}

int main(){
    int x,y;
    //入力
    cin>>s;
    cin>>k;
    //処理
    auto ans=solve();
    //出力
    cout << ans <<endl;
}
```
firebase login ができない時の対処法


#概要
ReactをFirebaseにHostingしようとした際にハマったのでメモ
#状況
```
yarn create react-app my-app
```
して

```
yarn add firebase-tools
```

して

```
firebase login
```

ちなみにこの後に聞かれるY/nはどっちでもいいです。

##エラー
![Firebase_CLI.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557680/ac985e23-594c-3e24-dd0f-198b9d8ac9c1.png)

何度やってもログインできない、、、。

#対処法
調べたらこれをするといいらしい。

```
firebase login --no-localhost
```

これでもできない場合はsslの検証をパスする以下の環境変数を設定します。

```
export NODE_TLS_REJECT_UNAUTHORIZED=0
```


```
firebase login
```

![Firebase_CLI-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557680/bc37c048-e83b-51d9-546c-a8eba6bdbd52.png)
***Woohoo!***

#解決
```
firebase init
```
:fire::fire::fire::fire:

```
? What do you want to use as your public directory? (public) //buildにします
```

```
yarn build
```

```
firebase deploy
```

で公開完了。
Ubuntu18.04上でのRuby + Railsのインストール(rbenv)

#目的
ネット上の記事を参考にしながら、RubyとRailsのインストールを試みたが、
躓いた点がいくつかあったため、一通りのインストール方法を備忘録として纏める。

#目次
1. rbenvのインストール
2. Rubyのインストール
3. Railsのインストール
4. 参考

#rbenvのインストール

rbenvをgitからクローンする。

```
$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
```

ruby-buildというプラグインをインストールすることで、
rbenvにRubyをインストールすることが出来る。

```
$ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
```

rbenvを使えるようにするため、.bashrcに設定を記述する。

 =>rbenvのpathを環境変数PATHに追加する。

```
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
```

=>rbenvを初期化する。

```
$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
```

#Rubyのインストール

インストール出来るrubyのバージョンを確認する。

```
$ rbenv install --list-a

1.8.5-p52
1.8.5-p113
1.8.5-p114
1.8.5-p115
1.8.5-p231
1.8.6
1.8.6-p36
1.8.6-p110
1.8.6-p111
1.8.6-p114
  :
  :
```

rubyをインストールする。

```
$ rbenv install 2.5.7
```

下記エラーが表示される場合は、エラーログに従ってパッケージをインストールしてから、
rubyをインストールする。

```
error: install `curl`, `wget`, or `aria2c` to download packages
error: failed to download ruby-2.5.8.tar.bz2

BUILD FAILED (Ubuntu 18.04 using ruby-build 20200520)

$ apt install wget
```

下記のエラーが表示される場合は、rbenvの関連パッケージをインストールしてから、
rubyをインストールする。
<font color="Silver">*私はこのパッケージを全てインストールすることで、エラーを改善することが出来ましたが、
　ここで記載しているパッケージを、全てインストールする必要はないかもしれません...
　必要ないパッケージが見つかりましたら、後ほど修正します。</font>

```
configure: error: in `/tmp/ruby-build.20200530061452.7106.ZgOAgp/ruby-2.5.7':
configure: error: no acceptable C compiler found in $PATH
```

```
$ apt update
$ apt install autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm5 libgdbm-dev
```

rubyがインストールされたことを確認する。

```
$ ruby versions
```

rubyをglobalかlocalに設定する。

```
$ rbenv gloval 2.5.7
$ rbenv local 2.5.7
```

 rubyがglobalかlocalの設定されたことを確認する。

```
$ ruby --version
```

#Railsのインストール

railsに必要なパッケージをインストールする。
libsqlite3-devは、Railsインストール時に必要
nodejsは、Rails起動時に必要

<font color="Silver">*もしかしたらsqlite3のインストールも必要かも...</font>

```
$ apt install libsqlite3-dev nodejs
```

railsをインストールする。
-v オプションでバージョンを指定出来る。

```
$ gem install -v 5.2.2 rails
```

railsがインストールされたことを確認する。

```
$ rails --version
```

プロジェクトの生成

```
$ rails new hoge_project
```

#参考
[ubuntuにRuby on Rails環境を構築してみよう！](http://exrecord.net/how-to-construct-ruby-on-rails-environment-in-ubuntu)
[rbenvを使ってUbuntu 18.04にRubyをインストールする](https://qiita.com/yuma-ito-bd/items/00f89ca0c04909c7c467)
C# 基礎

参照：https://www.runoob.com/csharp/csharp-encapsulation.html

a++; ++a; a--; --a
--

b = a++: 先将 a 赋值给 b，再对 a 进行自增运算。
b = ++a: 先将 a 进行自增运算，再将 a 赋值给 b。
b = a--: 先将 a 赋值给 b，再对 a 进行自减运算。
b = --a: 先将 a 进行自减运算，再将 a 赋值给 b 

```c#


using System;

namespace OperatorsAppl
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 1;
            int b;

            // a++ 先赋值再进行自增运算 a = 2, b = 1
            b = a++;
            Console.WriteLine("a = {0}", a);
            Console.WriteLine("b = {0}", b);
            Console.ReadLine();

            // ++a 先进行自增运算再赋值 a = 2, b = 2
            a = 1; // 重新初始化 a
            b = ++a;
            Console.WriteLine("a = {0}", a);
            Console.WriteLine("b = {0}", b);
            Console.ReadLine();

            // a-- 先赋值再进行自减运算 a = 0, b = 1
            a = 1;  // 重新初始化 a
            b= a--;
            Console.WriteLine("a = {0}", a);
            Console.WriteLine("b = {0}", b);
            Console.ReadLine();

            // --a 先进行自减运算再赋值 a = 0; b = 0
            a = 1;  // 重新初始化 a
            b= --a;
            Console.WriteLine("a = {0}", a);
            Console.WriteLine("b = {0}", b);
            Console.ReadLine();
        }
    }
}

```


Factorial
--
在数学与计算机科学中，递归是指在函数的定义中使用函数自身的方法。
　　递归算法是一种直接或者间接地调用自身算法的过程。在计算机编写程序中，递归算法对解决一大类问题是十分有效的，它往往使算法的描述简洁而且易于理解。
递归算法解决问题的特点：
　　(1) 递归就是在过程或函数里调用自身。
　　(2) 在使用递归策略时，必须有一个明确的递归结束条件，称为递归出口。
　　(3) 递归算法解题通常显得很简洁，但递归算法解题的运行效率较低。所以一般不提倡用递归算法设计程序。
　　(4) 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。所以一般不提倡用递归算法设计程序。在实际编程中尤其要注意栈溢出问题。

　　借助递归方法，我们可以把一个相对复杂的问题转化为一个与原问题相似的规模较小的问题来求解，递归方法只需少量的程序就可描述出解题过程所需要的多次重复计算，大大地减少了程序的代码量。但在带来便捷的同时，也会有一些缺点，也即：通常用递归方法的运行效率不高。



```c#
using System;
namespace Test {
    class Dummy {
        public int loop(int i) {
            int result;
            Console.WriteLine("i: {0}", i);
            if (i == 10)
            {
                return 10;
            }
            else {
                result = loop(i + 1) + i;
                return result;
            }
        }
        static void Main(string[] args) {
            Dummy d = new Dummy();

            Console.WriteLine("result: {0}", d.loop(6)); // result: 40
        }
    }
}

```
Excelで メニューを作る (Tips2)

##マクロMenu
Excelブックを開くとマクロMenuが、表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93227/d61f66d4-ac39-8ef8-dda7-b36e59867070.png)

##マクロMenuに表示するには
［システム設定］シートの【マクロメニュー名】にマクロメニューに表示するマクロ名を登録します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93227/0dd09002-511d-cf0e-269d-f1e4218d3652.png)


メニューには、マクロの名[Menu_ *** ]の[Menu_]より後ろの文字が表示されます。

```vb:ExcelBook.xlsm!Module
'2020/05/08 --------------------------------------------------*
Public Sub Menu_データ取得()
  F_データ取得.Show
  Unload F_Start_Menu
End Sub

'2020/05/08 --------------------------------------------------*
Public Sub Menu_データ集計()
  F_データ集計.Show
  Unload F_Start_Menu
End Sub

'2020/05/30 --------------------------------------------------*
Public Sub Menu_環境設定()
  F_Sys環境設定.Show
  Unload F_Start_Menu
End Sub
```

##データ取得
Access データベースの、Excelのシートにデータをインポートします。
インポートする項目は、自由に設定できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93227/77d236c6-e4ce-08db-ee9c-8ecbbab5ac8d.png)

##Excelの［データの取得］機能について
Excelの［データの取得］機能を解りやすく作成しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93227/1c03fc31-3ce7-8ba2-bc3d-59306a524608.png)

##Tips1のメニューから呼び出す。

Tips1のメニューに［データ取得］マクロを登録するとTips2のマクロを呼び出すことが可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93227/88754373-467a-a64c-6a89-3dca9c949b14.png)

ExcelツールPG100j.xlsm の［Menu_データ取得］マクロを実行する。

```ExcelLauncher.xlsm
ExcelツールPGv100j.xlsm!Menu_データ取得
```

Tips1 から Tips2 を呼び出す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93227/77d236c6-e4ce-08db-ee9c-8ecbbab5ac8d.png)

このようにして、グループ化した Excelのマクロの一部を 単一のマクロパーツとして呼び出せるようにします。
Docker Desktop for WSL2のKubernetesコンテキストをWSL2と同期する

Windows側のシステムトレイ上のDocker Desktop for WSL2メニューにあるKubernetesコンテキストを、WSL2側の`~/.kube/config`と同期するための手順です。同期することで以下のようなことができるようになります。

- WindowsのシステムトレイにあるDocker DesktopメニューからKubernetesコンテキストの参照および切り替えができる。切り替えた場合はWSL2側にKubernetesコンテキストが反映される。
- WSL2側から`~/.kube/config`を更新した場合に、Docker DesktopメニューのKubernetesコンテキストに反映される。

> NOTE:
> そもそも何故この同期設定が盛り込まれてないのかが個人的には疑問です。どこかのタイミングでDocker Desktop for WSL2がこの同期設定に対応するかもしれないので、その際にはコメントをいただければ幸いです。

# 設定手順

WSL2およびDocker Desktop for WSL2がインストール済みで利用できる状態を想定しています。

1. Windows側(Docker Desktop)に`%USERPROFILE%\.kube\config`を作成する。既に存在する場合はスキップする。
2. Windows側の`~/.kube/config`を参照するシンボリックリンクをWSL2側に作成する。WSL2のターミナルから以下のようなコマンドを実行することで作成できる。既にWSL2側に`~/.kube/config`がある場合はバックアップを取るか削除すること。

    ```bash
    # システムドライブがＣドライブ、Windowsユーザがtaroの場合
    # NOTE: c, taroの部分は適切な値に置き換えること
    mkdir -p ~/.kube
    ln -s /mnt/c/Users/taro/.kube/config $HOME/.kube/config
    ```

これで設定完了となります。
なお、この設定手順ではWindows側の`./kube/config`がマスタファイルになります。


以下のようにWSL2側のKubernetesコンテキストとWindows側のDocker DesktopメニューのKubernetesコンテキストが同期していることが分かります。

<img width="626" alt="k8s-context-menu-01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174502/00ce3f2f-8d6e-6f63-2fec-6d70ad3b30cb.png">

以下はkindのKubernetesクラスタをWSL2上から作成した直後の画像です。kindのKubernetesクラスタが作成されるとWSL2側の`~/.kube/config`のKubernetesコンテキストが追加＆更新されますが、これがWindows側のDocker DesktopメニューのKubernetesコンテキストと同期していることが分かります。

<img width="630" alt="k8s-context-menu-02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174502/91ddcf7f-0444-6121-e687-c0dad153d95c.png">

> NOTE: 
> ちなみにWSL2のターミナルのシェルプロンプトの「絵文字 + カラフル文字」でのKubernetesコンテキスト表示は[kube-ps1.sh](https://github.com/jonmosco/kube-ps1)を利用して実現してます。Kubernetes上での開発や検証が多い人にはお勧めです。
【Rails】Action TextとActive Storageテーブルのデータ取得

## 概要
ArticleモデルでActionTextを使おうと思った場合、次のようにすれば「action_text_rich_texts」テーブルのデータを取得できるが、一緒に作成される他二つのテーブルのデータを取得できず四苦八苦した。。。

```ruby
class Article < ApplicationRecord
  has_rich_text :content
end
```

```zsh
$ Article.first.content
```

## 結果
それぞれ次のコードで取り出せた。

```zsh
$ ActiveStorage::Attachment
=> ActiveStorage::Attachment(
id:          integer, 
name:        string, 
record_type: string, 
record_id:   integer, 
blob_id:     integer, 
created_at:  datetime
)

$ ActiveStorage::Blob
=> ActiveStorage::Blob(
id:           integer, 
key:          string, 
filename:     string, 
content_type: string, 
metadata:     text, 
byte_size:    integer, 
checksum:     string, 
created_at:   datetime
)


$ ActionText::RichText
=> ActionText::RichText(
id:          integer, 
name:        string, 
body:        text, 
record_type: string, 
record_id:   integer, 
created_at:  datetime, 
updated_at:  datetime
)
```

## やりたかったこと
ActionTextに関連づいた画像を一覧表示して、画像にArticleの詳細ページへのpathを指定したかった。
とりあえず実現はできたが以下のような回りくどいコードになった。
外部キーも設定されているようだし、もっとうまいこと呼びだせると思うけど分からず、、、、
わかる方、是非教えていただけないでしょうかm(_ _)m

```ruby:app/controllers/pages_controller.rb
  def photo
    # 関連付けされているBlobのみ取得
    blob_ids = ActiveStorage::Attachment.pluck(:blob_id)
    @blob = ActiveStorage::Blob.where(id: blob_ids )
    # Blobに対応したログのidを取得
    attachment = ActiveStorage::Attachment.where(blob_id: @blob.ids)
    @link = attachment.pluck(:record_id)
  end
```

```html.erb
<div>
  <% @blob.zip(@link).each do |img, link| %>
    <%= link_to article_path(link) do %>
      <%= image_tag img %>
    <% end %>
  <% end %>
</div>
```
【初心者】Puppeteerでよく使うコードベスト3

# はじめに
毎月末になると、ルーティンで作業工数の入力をしています。
JavaScriptで半自動で入力していて、５分ほどで入力出来ています。
が、憂鬱すぎるので全自動化することにしました。
ググって最初に目に付いたPuppeteerを利用します。
実際に利用してみてベースとなるコード、更によく使うコードがわかったのでQiitaに残します。

# コード
### 基本のコード
```javascript:kihon.js
const puppeteer = require('puppeteer');
// ID・アカウント認証する時はここでID・アカウント情報を読み込む↓
// 後述
// ID・アカウント認証する時はここでID・アカウント情報を読み込む↑

(async () => {
    const browser = await puppeteer.launch({
        headless: false,  // ブラウザの動きを表示
        slowMo: 50  // puppeteerの操作を遅らせる
    })
    const page = await browser.newPage()

    // ページを開く
    await page.goto('https://www.google.com/')

    // 必要な処理を書く↓
    // 後述
    // 必要な処理を書く↑

    // ブラウザを閉じる
    await browser.close()
})()
```

#### ID・アカウント認証する時はここでID・アカウント情報を読み込む

```javascript
const {USER, PWD} = require('./config.json'); // 認証が必要であれば別ファイルのconfigファイルから読み込む
```

##### config.jsonの中身は以下
```json:config.json
{
    "USER":"xxx",
    "PWD":"xxx"
}
```


#### 必要な処理（よく使うコード）
今回だと使うコードは決まっていて、必要な値を入力して、ボタンをクリックして登録するだけでしたので以下の操作で事足りました。

```javascript
// 指定した時間待つ
await page.waitFor(10000); // ミリ秒

// 入力
await page.type("#IdUser", 'userName'); // セレクタ,入力文字。
await page.type("#IdUser", USER); // 変数の場合

// クリック
await page.click("#loginButton"); // セレクタ

// テキスト取得
const text = await page.$eval('td.timeHour', text => text.textContent) // セレクタ
```


### 最終的なコード
```javascript:kihonプラスα.js
const puppeteer = require('puppeteer');
// ID・アカウント認証する時はここでID・アカウント情報を読み込む
const {USER, PWD} = require('./config.json'); // 認証が必要であれば別ファイルのconfigファイルから読み込む

(async () => {
    const browser = await puppeteer.launch({
        headless: false,  // ブラウザの動きを表示
        slowMo: 50  // puppeteerの操作を遅らせる
    })
    const page = await browser.newPage()

    // ページを開く
    await page.goto('https://www.google.com/')

    // 必要な処理を書く
    // 指定した時間待つ
    await page.waitFor(10000); // ミリ秒
    // 入力
    await page.type("#IdUser", USER); // 変数の場合
    // クリック
    await page.click("#loginButton"); // セレクタ
    // テキスト取得
    const text = await page.$eval('td.timeHour', text => text.textContent) // セレクタ

    // ブラウザを閉じる
    await browser.close()
})()
```


# 参考
* 公式
 * [Puppeteer](https://pptr.dev/)
* 環境構築
 * [10分ではじめるpuppeteer](https://qiita.com/webmaster-patche/items/d400e798a49bbebb79af)
* サンプルコード
 * [puppeteerを体験してみた](https://qiita.com/AYA_iro/items/e5dd0956b3ba82f6bf31)
* よく使う操作解説
 * [Puppeteerを使った開発の勘所](https://qiita.com/taminif/items/1ba7f68aedd68bae5e09)