OmniAICreator/Qiita-1.07M huggingface dataset:
matlabのData Acquisition Toolboxを使う③ NI 9211

　アナログ入力を手軽に得る方法に、NIの測定ツールを使う方法があります。低速なものから高速なツールがあります。
　第1回で使ったUSB-6009（14ビット、差動4チャネル）は、低速で100Hzのサイン波程度までデータを取り込めました。第2回では、少しサンプリング速度の高いcRIO-9201（12ビット、シングルエンド8チャネル）は10kHzのサイン波程度までデータを取り込めました。
　ここでは、4チャネル熱電対もしくは±80mVの24ビットA-Dコンバータである9211を利用します。収納するケースが何種類かあり、ここでは、一番安価な、
　　NI cDAQ-9171　NI CompactDAQ 1 スロットバス電源駆動 USB シャーシ
に取り付けて使いました。
<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/b637d6ef-3b34-c99e-7e7b-e49aeb2b21b7.png">!

　USBケーブルでPCとつなぐだけで準備は終わります。ここでは、入力端子0-1に熱電対Kタイプを取り付けました。

###アプリAnalog Input Recorderを起動

　Data Acquisition Toolboxをインストールすると、Analog Input Recorder、Analog Output Generatorがアプリに登録されています。Analog Input Recorderを起動します。9211を探し出してきて、入力波形を表示します。
　熱電対の起電力を読み取っているので、ほとんど変化しません。

![スクリーンショット 2021-01-23 14.27.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/a816c622-f3c0-e836-7e87-c61c155411c1.png)

　画面上部の右端にあるGenerate Script codeをクリックします。

###Acquire Temperature Data From a Thermocouple

　ヘルプで、Acquire Temperature Data From a Thermocoupleの解説ページを見つけます。ここでは、電圧で取得したデータを熱電対用に変更する手順が書かれています。上記のコードを修正しました。

```matlab
%Create a DataAcquisition object for the specified vendor.
dq = daq("ni");
dq.Rate = 7;

%Add channels and set channel properties, if any.
ch = addinput(dq, "cDAQ1Mod1", "ai0", "Thermocouple");
ch.ThermocoupleType = 'K';
ch.Units = 'Celsius';

%Read the data in timetable format.
samples = 60;
data = read(dq,seconds(samples))
summary(cDAQ1Mod1_1)
dataM = movmean(data.cDAQ1Mod1_ai0, 40);
dataS = smoothdata(data.cDAQ1Mod1_ai0);

%Plot the read data on labeled axes.
plot(data.Time, data.cDAQ1Mod1_ai0);
hold on
plot(data.Time, dataM,'LineWidth', 2);
hold on
plot(data.Time, dataS,'LineWidth', 2)
ylabel('温度 [℃]');
grid on;
xlabel("時間");
```

　1分ロギングした実行結果です。青色が生データで、赤色が40回の移動平均です。黄色はお任せ移動平均の結果です。
![ni201.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/b5e3d955-4e4e-d2a9-3274-d561f57de389.png)

　10分間のデータです。

![スクリーンショット 2021-01-23 15.42.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/2466b756-c343-0072-ec35-a313d17faa45.png)
【ExcelVBAを使った社内開発】依頼フォーマットを作ってあげたら依頼が急に増えた

ちょっと仕事が忙しくなりブログが久しぶりになってしまいました。
今日はどうして忙しくなったか書きたいと思います。

#ワタシの仕事内容
以前も書いたのですが私の仕事は、社内の各部署から業務自動化の依頼を受けて、VBAでツール開発をするお仕事です。
社内の担当範囲となる部署は広範囲で、自分が所属する部署以外の依頼も受けます。
私が入社するちょっと前からできた業務自動化チームで、上司も素人。
私もプログラム書くことはできるけど全体の流れを考えるなどは色々と日々手探りで仕事を進めてます。
以前仕事内容について書いたブログはこちら（[ExcelVBAを使った社内開発の心構え～未来の自分と後から来る誰かのために～](https://qiita.com/KaoTechBlog/items/14c60dd6f7ed0bf54f6e)）
（現在、同僚の子が退職しましたのでチームは私と上司の2人になりました。）

#社内開発依頼の現状と課題
依頼がある際は、どんなことを自動化したいかまとめてもらいご依頼いただく形なのですが、
数件は依頼はあるものの、中々コンスタントに新規開発依頼があるわけではなくちょっと手持ち無沙汰になることもしばしばありました。（ま、そういう時にブログとか書いていたんですけどね）

依頼の仕方はというと、「依頼したいことをまとめてもらう際のフォーマットは特にないです。ご自由なスタイルにまとめてからご連絡ください」というスタイルにしてました。
なのでうすぺらーい内容だったり、書いてほしいことが抜けていたり、その度に依頼者にもどして、また書き直してもらってっていうやり取りも多かったです。
またその__「自由に書いてください」__というのが依頼者にとってはハードルが高いのかも・・・と思っておりました。

#「自由は不自由なのだ！」だから、依頼フォーマットを作ってみた
依頼に必要な内容はなんとなくわかるけど、自由にまとめるとなると難しい…
ある程度決まった型にはめて行くほうがそりゃ楽ですよね。
そこで以下のようなフォーマットシートを作成し、記入例もつけました。

####【依頼内容シート】
依頼に必要なデータを記入してもらう
(依頼者の情報や納期、サンプルファイルの格納場所)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700414/a6677740-0a46-c816-c117-53fe0bbcb78f.png)

####【動作イメージシート】
実際にどんなことをツールでやりたいか記入してもらう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700414/db69a49a-43ba-afce-edc0-65ff91be4f3a.png)

####【記入例】
__自動化イメージ__
「以下のようなデータがあるとして、これをエリアごとのデータにして、それぞれのファイルで保存したい」という実際にあったデータ分割ツールの依頼例です。
依頼フォーマットシートにはこの記入例のシートも付けています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700414/f0484f79-b45b-5c5c-df92-4f4f1e27d8ee.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700414/dbae69e0-29df-eebd-6b6e-227a9f8f8efc.png)
__【動作イメージシート】記入例__
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700414/72416240-000e-0f0f-881d-8263fbb0ff27.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700414/8e9901a3-0e59-666c-95ad-d850ca925bc1.png)

#依頼フォーマットの利点
####依頼内容が見やすく分かりやすい
今まで依頼者それぞれにまとめてくれていた依頼の資料ですが、スタイルがまとまっていたほうが
どこに何が書いてあるかすぐに分かるし読みやすいです。

####足りてない情報を事前に確認しやすい
依頼者も必要項目を埋めなければならないので、「あ、サンプルファイル用意しなけいけないんだ」とか気づけるし、こちらも抜けてる情報があればすぐ指摘できます。

####MTG時間の短縮
実際にツール作成作業に入る前に仕様確定MTGを行っているのですが
事前にフォーマットの内容をしっかり詰めて依頼内容を確認しておくことによりその後のMTGがスムーズに進みます。

####依頼者が自分で業務内容を整理するきっかけにもなる
みんながみんな依頼内容を最初から完璧に記入できるわけではないですが、それでも「まず自分たちで考えみる」ということに意味があると思います。
記入しているうちに、
「あ、この部分って1回にまとまられるよね」とか「そもそもこの作業いらなくない？」と気付けることもあるかと思います。

#最後に
「今後はこのフォーマットに必要事項を記入してご依頼ください」と周知したところ、
依頼者にとっても依頼しやすくなったのか、依頼が一気に増えました。
周知後、月1～2件だった依頼が、5～6件ほど抱えることになりました。
というわけで、最近納期に追われめっきり忙しく過ごしております！
「フォーマットがあったほうがいい」って結構当たり前のことですが、作って運用してみて初めて気づきました:sweat_smile:
一番良かったのは依頼数が増えて社内の業務自動化が少しでも進んだことと、依頼者が自分で考えるきっかけになることですかね:wink:
もちろんこのフォーマットがあっても「そんなの面倒くさいから書きたくないし考えたくない、でも自動化はしたいからなんとかしてくんない？」って言う人はいます。
私は甘やかさないので、そういうご依頼は上司を通じて丁重にお断りします:joy:！
でもそうやって真剣に自動化ツールなどの依頼したい人だけにふるいをかけられるのもいいかなと思います。

フォーマットのスタイルもこれからもっと依頼者の方が書きやすいように改善していきたいな。
Q28.[Network] Can you login？を解くまでの過程

##Q28.[Network] Can you login？にチャレンジしてみる
>https://ctf.cpaw.site/questions.php?qnum=28
>古くから存在するネットワークプロトコルを使った通信では、セキュリティを意識していなかったこともあり、様々な情報が暗号化されていないことが多い。そのため、パケットキャプチャをすることでその情報が簡単に見られてしまう可能性がある。
次のパケットを読んで、FLAGを探せ！ 

「network100.pcap」をDLしてとりあえずWireSharkで見てみる

とりあえずざっと上からなぞると![hint.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517314/a1174d97-12af-6039-a812-3b852b5357ab.jpeg)

どうやらディレクトリの中にFLAGがあるらしい
レベル1みたいにキャプチャの中に答えがあるわけではないのか・・・

##FTP通信は非暗号
>TCP/IP - FTPとは - ネットワークエンジニアとして
>https://www.infraexpert.com/study/tcpip20.html

問題文にもある古くから存在するプロトコルとはFTP通信のことであることが伺える
そこに着目してみてみると・・・
![login.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517314/75c4cb73-6dd7-9e94-765f-a18138fbf8a4.jpeg)

"157.7.52.186"というファイルサーバに対して下記のID、PASSでログインが成功していることがわかる
ユーザー名：cpaw_user
パスワード：5f4dcc3b5aa765d61d8327deb882cf99

それより以前にもID,PASSともに"anonymous"でログインを試みているが失敗している
アノニマスFTPの場合IDはanonymousが一般的なのでとりあえず打ってみた感じ
IDもPASSも知っているのにわざわざ試したのか・・・

とりあえずIDとパスワードは分かったので自分でもログインを試みてみる

##FTPサーバ(157.7.52.186)にアクセスする
ftp 157.7.52.186を実行してログインする

```
root@kali:/home/kuratsuka# ftp 157.7.52.186
Connected to 157.7.52.186.
220 Welcome to Cpaw CTF FTP service.
Name (157.7.52.186:kuratsuka): cpaw_user
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>
```


ログインしてみたので答えがあるディレクトリを探したいのでとりあえずls -aで中になにがあるかを見てみる


```

ftp> ls -a
200 PORT command successful. Consider using PASV.
^C
421 Service not available, remote server has closed connection
```

PASVを使うことを検討してねと言われて中を見ることができない・・・・！！！
ctrl+Cでキャンセルかけたらリモートも切断されたので再try！

##FTPにおけるアクティブとパッシブ

FTPのデータコネクションにおいてアクティブとパッシブの2つのモードがあり
主な違いはコネクションの確立方法らしい
>参考ｰCentOSサーバー構築入門ｰ
>http://cos.linux-dvr.biz/archives/131

とりあえずpassiveと入力してパッシブモードでコネクションしてみる

```
ftp> passive
Passive mode on.
ftp> 
ftp> ls -a
227 Entering Passive Mode (157,7,52,186,234,114)
150 Here comes the directory listing.
drwxr-xr-x    2 ftp      ftp            42 Jun 18  2019 .
drwxr-xr-x    2 ftp      ftp            42 Jun 18  2019 ..
-rw-r--r--    1 ftp      ftp            39 Sep 01  2017 .hidden_flag_file
-rw-r--r--    1 ftp      ftp            36 Sep 01  2017 dummy
226 Directory send OK.
```

無事に見ることができました
.hidden_flag_fileが怪しいのでとりあえずgetコマンド

###FLAGがあった！
catコマンドで中身を見てみると

```
root@kali:/home/kuratsuka# cat .hidden_flag_file 
cpaw{f4p_sh0u1d_b3_us3d_in_3ncryp4i0n}
```

FLAGがあった!!!
ガウス・マルコフの定理について

#はじめに
千葉大学/Nospareの[米倉](https://sites.google.com/site/shoutoyonekura/)です．今回は最近ちょっと話題になった，「ガウス・マルコフの定理」についての解説と，Juliaを用いた簡単な数値実験を紹介したいと思います．

#設定
定理の内容を解説する前に，問題の設定をまず述べます．$\mathbf{y}$を$n$次元の被説明変数，$\mathbf{X}$を$n\times p$の説明変数の行列，$\beta$を$p$次元のベクトルとして，回帰モデル$\mathbf{y}=\mathbf{X}\beta+\epsilon$を考えます．$\epsilon$は$\mathbb{E}[\epsilon]=0$，$\mathrm{Cov}[\epsilon]=\sigma^{2}\mathbf{I}$をみたす，$n$次元の確率ベクトルです．ここで，$\mathbf{I}$は$n$次元の単位行列です．

この時，最小二乗推定量(OLSE)はある仮定の下で$\hat\beta_{OLSE}=(\mathbf{XX^{\top}})^{-1}\mathbf{X^{\top}y}$となり，その分散は，$\mathrm{Var}[\hat\beta_{OLSE}]=\sigma^2(\mathbf{X}^{\top}\mathbf{X})^{-1}$と計算できます．また$\mathbb{E}[\hat\beta_{OLSE}]=\beta$も成立し，OLSEは不偏推定量です．

ガウス・マルコフの定理が述べているのは，<font color="Red">任意の不偏かつ線形な推定量の中で，OLSEの分散が最小になる</font>ということです．これをもって，OLSEは best linear unbiased estimator (BLUE)と言われます．証明についてはネットで検索するといくつか見つけられるのでそちらを参照してみてください．

#数値実験
ガウス・マルコフの定理の意味を視覚的に理解するために次の様な実験をしてみました．
今$n=21$とし，$\beta=[1.0,2.0]^\top$と真値を定めます．また$\mathbf{X}$の１列目は全て１，２列目は標準正規分布から21個乱数を発生させて格納し，$\mathbf{y}=\mathbf{X}\beta+\epsilon$とデータ$\mathbf{y}$を作りました．ここで，$\epsilon\sim\mathcal{N}(0,2\mathbf{I})$です．$\mathbf{X}$は固定し，$\epsilon$を10,000回独立に発生させることによって，サンプルサイズ21のデータセットを10,000個作成しました．

このデータに対して，推定方法を2つ考えます．まずは普通のOLS推定です．次に，21個のデータを3等分しそれぞれでOLS推定を行い，最後にその平均を取るという推定方法を考えました．これも不偏推定量であることがわかり，分割推定量と呼ぶことにします．

次の図は以上の手続きで求めた10,000個の$\beta=2$に対する推定値を元にして，その密度をプロットしたものです．青い線がOLSE，オレンジの線が分割推定量の結果です．まず二つともバイアスが無いことが分かります．一方で，OLSEの方が分割推定量よりも密度関数の裾が小さい（分散が小さい）ことが分かると思います．これがガウス・マルコフ定理が述べていることです．参考までに，Juliaのコードを載せておきます．
![Screenshot (173).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1040197/25bad056-4d12-8dd3-ad27-e0a059c2a927.png)



```Julia
using Plots
using Statistics
using StatsPlots
theme(:ggplot2)   

reps = 10000 
n = 21 
sig = 2.0  
x = [ones(n,1) randn(n,1)]  
beta = [1.0, 2.0] 
Pop = x*beta

estimate = zeros(reps,2) 

for i = 1:reps
	
	e = sig*randn(n)
	y = Pop + e
	# OLSE
	estimate[i,1] = (y\x)[2]

    # average of split estimator
	y1 = y[1:7,:]
	y2 = y[8:14,:]
	y3 = y[15:21,:]
	x1 = x[1:7,:]
	x2 = x[8:14,:]
	x3 = x[15:21,:]
	beta_ss1 = y1\x1
	beta_ss2 = y2\x2
	beta_ss3 = y3\x3
	beta_ss = (beta_ss1 + beta_ss3 + beta_ss3)/3.0 # average 
	estimate[i,2] = beta_ss[2]
end

density(estimate[:,1],lab="OLS")
density!(estimate[:,2],lab="Split")
```
#最近話題になったこと
OLSEは「不偏」で「線形な」推定量の中で分散が最小になりますが，最近[Bruce E. Hansen, A Modern Gauss-Markov Theorem.](https://www.ssc.wisc.edu/~bhansen/papers/gauss.pdf)で「線形」が外せることが示されました．つまり，線形とは限らないより広い不偏推定量のクラスの中でOLSEの分散は最小になることを意味しています．これは教科書の内容を書き換える必要がある中々凄い結果だと思います．なのでBLUEではなく，BUEになってしまい，どう発音するかまだ定まってません．ブゥとかだとカッコ悪いですね．

#終わりに
株式会社Nospareでは統計学の様々な分野を専門とする研究者が所属しております．統計アドバイザリーやビジネスデータの分析につきましては[株式会社Nospare](https://bit.ly/38WtGZH) までお問い合わせください．
<a href="https://bit.ly/38WtGZH">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1023506/d5c625c0-d6f4-680b-d702-3c40f11d6c39.jpeg" alt="株式会社Nospare" width=400>
</a>
Amazon Linux 2のhostname変更方法

##### はじめに
AmazonLinux2でEC2を立ち上げ、 `hostsファイル` と `networkファイル`を編集してhostnameを変更後にLinuxを再起動後に再度SSH接続してもhostnameが変更されていないという場面で遭遇しました。
そのため、AmazonLinux2でのhostname変更方法の忘備録を残しておきたいと思います。  

##### 変更方法

`hostnamectl`コマンドでhostnameを変更する

```
# hostnamectlコマンドで変更前のhostnameを確認する
[ec2-user@ip-10-0-11-229 ~]$ hostnamectl　
   Static hostname: ip-10-0-11-229.ap-northeast-1.compute.internal　←変更前のhostname
         Icon name: computer-vm
           Chassis: vm
        Machine ID: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
           Boot ID: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    Virtualization: xen
  Operating System: Amazon Linux 2
       CPE OS Name: cpe:2.3:o:amazon:amazon_linux:2
            Kernel: Linux 4.14.209-160.339.amzn2.x86_64
      Architecture: x86-64

# hostnameコマンドでhostnameを変更
[ec2-user@ip-10-0-11-229 ~]$ sudo hostnamectl set-hostname hogehoge

# hostsファイルの変更
[ec2-user@ip-10-0-11-229 ~]$ cat /etc/hosts
127.0.0.1  hogehoge localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost6 localhost6.localdomain6

# インスタンスの再起動
[ec2-user@ip-10-0-11-229 ~]$ sudo reboot

# SSH接続
$ ssh -i hogehoge.pem ec2-user@XX.XXX.XXX.XXX

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
[ec2-user@hogehoge ~]$
```

##### まとめ
hostnameを変更するにはhostnamectlを使って変更しないと反映されないみたいなんですね。
仮想化に関する基礎知識

#はじめに
この記事は「仮想化とは何ぞや？」という根本的な情報を整理するための記事です。

#前提知識として
仮想化の説明の前にコンピュータの基本的な構造を押さえておく必要があります。
コンピュータは非常に大まかにいうと下記のような階層構造になっています。

>高　アプリケーション
>｜　ミドルウェア
>｜　OS
>｜　ファームウェア
>低　ハードウェア

アプリケーション：ウェブブラウザのような特定の動作をするプログラムがここに属します。
ミドルウェア：Javaのようなアプリケーションが動作するための環境がここに属します。
OS：WindowsやLinux等がここに属します。
ファームウェア：OSとハードウェアを仲介するソフトウェアがここに属します。
ハードウェア：メモリやCPU、ハードディスクといった物理的な部品がここに属します。

#仮想化とは
「仮想」という言葉について、辞書を引いてみると以下のような説明が出てきます。

>実際にはない事物を、仮にあるものとして考えてみること。仮に想定すること。
>　　　　　　　　　　　　　　　　　　　　　　　　引用元　デジタル大辞泉

IT業界において「仮想化」とは前述した階層構造において「自身よりも低い層のもの」を「仮にあるもの」として動作させることを言います。

例えば、前述の構成のOSを「仮想化する」という場合、OSより低い層にあたる、ファームウェアとハードウェアを「仮にあるもの」として動作させるということです。

>高　アプリケーション
>｜　ミドルウェア
>｜　OS★OSを仮想化する場合
>｜　ファームウェア（仮にあるとする）
>低　ハードウェア（仮にあるとする）

#仮想化登場以前
昔はハードウェアとOSは1対1で結びついていました。
コンピュータが1台あるとすれば、その上で動作するOSは1つで、他のOSを動作させようとするなら、OSをインストールし直す必要がありました。※デュアルブートについてはここでは割愛します。

コンピュータの性能が凄まじい速度で向上し、いろいろなサービスがコンピュータの上で稼働するようになりました。その結果として、サービスを提供する側にとっては困ったことが起こります。

OSとハードウェアが1対1で結びついているので、サービスを動かすために必要なOSが複数ある場合、コンピュータ(ハードウェア）も複数必要になるのです。
ハードウェアが複数必要ということは、物理的なモノを置くためのスペースを確保しなければなりません。コンピュータは電気で動きますので、電源も必要です。

結果として、大規模なサービスを展開するためには、コンピュータを買うお金（機器代）、物理的なスペースを確保するためのお金（家賃）、コンピュータを動かすためのお金（電気代）がかなりの金額としてかかることになりました。

#仮想化の登場
かなりの金額をかけてサービスが稼働したとします。
では、サービス稼働後の状況を見てみましょう。

サービス稼働後、当然ですがユーザがサービスを利用すれば、コンピュータが処理をしますので、それだけリソースを使用します。非常に多くのユーザがサービスを利用すれば、ひょっとするとサービスが落ちてしまうこともあるかもしれません。

しかし実際問題として、「非常に多くのユーザ」が「常に」「サービスを利用している」ということはありません。これはつまり時間帯やサービスによっては「コンピュータのリソースが余っている」ということが起こりえるということです。

機器代＋家賃＋電気代とお金をかけたのに、「使用されるリソースは半分もいかない」
こんな状況を解決するための手段として、「仮想化」が登場/普及しました。

#仮想化は何をしているのか
前述したとおり、「仮想化」とは「自身よりも低い層のものを仮にあるものとして動作させること」です。これによって1台のハードウェア上で複数のOSを動作させることが可能になりました。

ここではOSを仮想化した場合を例に、実際にどんなことをしているのかを説明します。

OSを仮想化する場合、OSより低い層であるファームウェアとハードウェアが仮にあるものとして動作させるということです。

OSが何か処理をする場合、以下のような流れで動作しています。
1：ハードディスクやSSDから必要なデータを読み取る
2：メモリに必要なデータを広げる
3：CPUで処理してもらう
4：処理の結果を受け取る

共通しているのはOSは結果を受け取るまでは、あくまでハードウェア(CPUやメモリ)にお願いしているということです。

非常に雑な言い方ですが、OSからすれば、処理のお願いを聞いてくれて、結果を返してくれるのであれば、その過程はどうでもいいのです。

OSを仮想化する場合は、「あるソフトウェア」がOSからの処理のお願いをハードウェアのふりをして受け取り、結果をハードウェアのふりをして返すということをしています。

この自身より低い層（ここではハードウェア）のふりをしてくれる「あるソフトウェア」を「ハイパーバイザ」と呼びます。ハイパーバイザは以下のようなことをしてくれています。

1：ハードウェアのふりをしてOSから処理のお願いを受け取る
2：ハードウェアに渡して処理をしてもらう
3：ハードウェアから処理の結果を受け取る
4：ハードウェアのふりをしてOSに結果を返す。

#仮想化のメリット
前述した「OSの仮想化」をするとハイパーバイザというソフトウェアがハードウェアのふりをしてくれます。つまりハイパーバイザがハードウェアのふりを頑張ってくれれば、OSを複数動作させられるということです。

ハードウェアとOSは1対1という既存の構成ではなく、1対Nという新しい構成を取れるようになります。以前は10台のコンピュータ(ハードウェア)が必要だったサービスが、リソースさせ足りているならば、3台のコンピュータ(ハードウェア)で事足りるということになりました。

10台から3台に減ることで、機器代が安くなります。さらに使用するスペースが減るので、家賃も減らせるかもしれません。稼働させる台数が減ったことで、電気代も浮くことになりました。

#仮想化のデメリット
仮想化のメリットは前述したとおりです。お金を節約できる可能性が多いにあるということです。

しかし当然、デメリットも存在します。
それは構成が複雑になる分、保守が大変になる可能性があるということです。

OSがハードウェアからのエラーを検知した場合、仮想化以前であれば、そのエラーはファームウェア、またはハードウェアに起因するものとして解析が進められるでしょう。
仮想化後はそこにハイパーバイザというソフトウェアが加わります。

OSとハイパーバイザの相性問題、ハイパーバイザとハードウェアとの相性問題等、解析が難しい部分が出てくることになりました。

これは既存のシステムを仮想化しようという場合に、十分に考慮するべき箇所であるといえます。

#最後に
かなりおおざっぱですが仮想化に関する基礎知識を書き出してみました。
突っ込みどころ等はコメントをいただれば幸いです。
【PHP】初中級者が解くべき過去問精選 100 問を解いてみた【１問目/100】

アルゴリズムのアウトプット

ということで、
[レッドコーダーが教える、競プロ・AtCoder上達のガイドライン【中級編：目指せ水色コーダー！】](https://qiita.com/e869120/items/eb50fdaece12be418faa#2-3-%E5%88%86%E9%87%8E%E5%88%A5%E5%88%9D%E4%B8%AD%E7%B4%9A%E8%80%85%E3%81%8C%E8%A7%A3%E3%81%8F%E3%81%B9%E3%81%8D%E9%81%8E%E5%8E%BB%E5%95%8F%E7%B2%BE%E9%81%B8-100-%E5%95%8F)@e869120さん



>AtCoder で水色コーダー、つまりレーティング 1200 を少ない問題数で達成するために、茶色コーダー・緑コーダーにとって適切な教育的良問を 100 問集めました。

こちらの記事の初中級者が解くべき過去問精選 100 問
をPHPで解いていきます。

```php
<?php

while (true) {
    $s = trim(fgets(STDIN));
    $s = str_replace(array("\r\n","\r","\n"), '', $s);
    $s = explode(" ", $s);
    $n = $s[0];
    $x = $s[1];
    if ($n == 0 && $x == 0) {
        break;
    }
    $ans = 0;
    for ($i = 1; $i <= $n; $i++) {
        for ($j = 1; $j <= $n; $j++) {
            for ($k = 1; $k <= $n; $k++) {
                if ($i < $j && $j < $k && $i + $j +$k == $x) {
                    $ans++;
                }
            }
        }
    }
    echo $ans . "\n";
}
```
典型的な全列挙の問題。
[awk]小数の切り上げ(速度比較)

- 小数の切り上げ処理という頻度の高い処理をawkで行うためのメモ
- 大体記法や速度の面において、忘れるため備忘録として記録。

## 結果
- 以下の内容から、方法２の方が速い。
- ただ可読性や速度の誤差の点から、方法1を利用する。
- **※forを利用した方法は、awkでは順番が変わるため記録としては除外。**

## 内容

```bash
# テストデータ作成
seq 1 0.2 100000 > number

# 最初の10行表示
cat number | head -n 5

1
1.2
1.4
1.6
1.8

# 方法1 int関数を用いる
cat number | awk '{r=int($1); print (r==$1) ? r : r+1}' | head -n 5

1
2
2
2
2

# 方法1の速度検証
# 0.00s user 0.00s system 1% cpu 0.492 total
time cat number | awk '{r=int($1); print (r==$1) ? r : r+1}' > /dev/null

# 方法2 printfを利用する
cat number | awk '{printf("%d\n",$1+=$1<0?0:0.999)}' | head -n 5

1
2
2
2
2

# 方法2の速度検証
# 0.00s user 0.00s system 0% cpu 0.476 total
time cat number | awk '{printf("%d\n",$1+=$1<0?0:0.999)}' > /dev/null
```

## 参考
- https://okwave.jp/qa/q4317424.html
- https://blog.kunst1080.net/post/2015/04/04/112808/
Laravel 7以降のBladeコンポーネントはどう便利になったか

Laravel 7で、Bladeコンポーネントが拡張された。最初知ったときは、わざわざHTML風の
文法になっているのがいまいちだと感じたが、よく調べてみるとしっかりとした意図のあ
る仕様で、便利そうだった。

どう変わったのか、またどう便利になったのか、具体的に紹介する。


参考:
[リリースノート 7.x Laravel](https://readouble.com/laravel/7.x/ja/releases.html) の"Bladeコンポーネントタグと向上"以下。


# 変更点

ほかにも細かいものはあるが、主に以下の3つが重要だろう。


## 1. `<x-.../>`とHTMLタグのように呼び出せるようになった

HTMLタグのように書くことができる。この呼び出し方では、自動的に`resources/views/components`以下のビューがコンポーネントとして呼び出される。

渡すデータも、HTML属性のように表記できる。PHPの変数を渡したい場合は、先頭に`:`を付加する。


```blade
{{-- Laravel 6まで --}}
@component('form.input.number', ['name' => 'foo', 'min' => 0, 'max' => $max])
@endocmponent
```

```blade
{{-- Laravel 7から --}}
<x-input.number name="foo" min="0" :max="$max" />
```

あるいは、

```blade
<x-input.number name="foo" min="0" :max="$max">
</x-input.number>
```


## 2. HTML属性を簡単に渡せる"属性バッグ"が追加された

渡した変数を`{{ $attributes }}`だけで表示できる。下記の例のようにオプションとして使う場合にはより有用だ。


```blade:resources/views/form/input/number.blade.php
{{-- Laravel 6まで --}}
<input type="number" name="{{ $name }}" @isset ($min) min="{{ $min }}" @endisset @isset ($max) max="{{ $max }}"@endisset value="{{ old($name) }}">
```

```blade:resources/views/components/input/number.blade.php
{{-- Laravel 7から --}}
<input type="number" {{ $attributes }} value="{{ old($name) }}">
```


## 3. Bladeビューとしてではなく、PHPのクラスとしてコンポーネントを表現するコンポーネントクラスを作れるようになった

これにより、コンポーネントが受け取るデータを明示することができるようになったのが非常に強力だ。

ほかにも、コンポーネントクラスに実装したメソッドをビュー側で変数として使用することができる。


```php:app/View/Components/Input/Number.php
<?php

namespace App\View\Components\Input;

use Illuminate\View\Component;

class Number extends Component
{
    /** @var string */
    public $name;

    /**
     * インスタンスを生成する
     *
     * @param  string $name
     * @return void
     */
    public function __construct(string $name)
    {
        $this->name = $name;
    }

    /**
     * ビューを取得する
     *
     * @return \Illuminate\Contracts\View\View
     */
    public function render()
    {
        return view('components.input.number'); # あるいは、文字列をそのまま返すこともできる
    }
}
```


# まとめ: どう便利になったのか

上記のサンプルコードを見れば大体わかると思うが、もう少し説明すると、

1. 呼び出し側はHTML風の文法のおかげで、短くわかりやすく書けるようになった。
2. コンポーネント側は属性バッグのおかげで、オプションの属性を短くわかりやすく書けるようになった。
3. コンポーネントクラスのおかげで、コンポーネントが受け取るデータを型を含めて明示することができるようになった。
4. また、関連するロジックをコンポーネントクラスに入れることができるようになった。

といったところだろうか。

ただ個人的には、コンポーネントクラスはそこまで必要ないと思っている。追加の属性値に関しては属性バッグでシンプルに書けるようになり、また紹介しなかったが`@props()`を使うことでも受け取るデータの名前に関しては明示できるようになっているためだ。

どちらにしてもメリットが強力で、デメリットも特に見当たらないため、Laravel 7以上が使える環境であれば、Bladeコンポーネントの新機能を使わない理由はなさそうだ。


参考:
[Bladeテンプレート 7.x Laravel](https://readouble.com/laravel/7.x/ja/blade.html) の"コンポーネント"以下。


# この記事のライセンス

![クリエイティブ・コモンズ・ライセンス](https://i.creativecommons.org/l/by/4.0/88x31.png)
この文書は[CC BY(クリエイティブ・コモンズ表示4.0国際ライセンス)](http://creativecommons.org/licenses/by/4.0/)で公開する。

この文書内のサンプルコードはMITライセンスで公開する。
STM32 nucleoを使う (7) PWMによるLEDの調光

#はじめに
STM32の汎用タイマーの使用例としてPWMをあげます。PWMはモーター制御や音源、調光などいろいろな用途で使われています。
汎用タイマのTIM2を使いLEDをPWMで点灯させます。

#PWM
PWMはPulse Width Modulation:パルス幅変調の意味でパルス波のデューティを変化させて変調します。

タイマーでPWMを実現するには、まず周期を設定します。その周期の中でHの期間をコンペア値で設定します。

![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68712/5b382768-ff9b-679a-c0a1-080ba11797cd.png)

LEDの制御なので周期は1kHzとします。分解能は0.1%以上にしたいと思います。

#LED設定
NUCLEO-F303REのユーザーLEDはTIM2が接続されています。
![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68712/2983ae6b-c2d5-40bf-9b29-53f2297648e7.png)
PA5端子をクリックしTM2_CH1を選択します。

#TIM2設定
Pinout & Configurationを選択し、Timersを広げ、TIM2をクリックします。
Clock Sourceを"Internal Clock"に、Channel1を”PWM Generation CH1”にします。
ConfigurationのParameter Settingタブを選択します。
Prescalerは72にします。クロックソースは72MHzなので72分周すると1MHzになります。
Counter Periodは999にします。
![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68712/701cd83d-1d92-cc29-eaa8-ef88208a12dd.png)


#コード
TIM7で10msのタイマー割り込みを発生させ、割り込み中でPWMのデューティを設定します。

##割り込みハンドラー
タイマー割り込みで10回ごとにデューティ比を設定した配列の値を読み込み、コンペア値に変換し設定します。
コンペア値の設定は__HAL_TIM_SET_COMPARE()で行います。

```C++
/* USER CODE BEGIN PV */
uint16_t	pwmTbl[] ={
		0,20,40,60,80,100,80,60,40,20,
};
/* USER CODE END PV */

/* USER CODE BEGIN 0 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){

	static unsigned char count = 0;
	static unsigned char stage = 0;
	int tblSize = sizeof(pwmTbl)/sizeof(uint16_t);
	uint32_t width;

	if(htim == &htim7) {
		count++;
		if (count >= 10) {
			count = 0;
			stage++;
			if (stage >= tblSize) {
				stage = 0;
			}
			width = (999*pwmTbl[stage])/100;
			__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, width);
		}
	}
}
/* USER CODE END 0 */
```
##main
メイン処理はタイマーの設定を行います。
HAL_TIM_PWM_START()でPWM動作を開始します。

```C++
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();
  MX_TIM7_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start_IT(&htim7);
  /* tim7 Start */
  HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
  /* PWM Start*/
  __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 0);
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
```
LEDの明るさが変わるはずです。

STM32の使い方を学習した内容をまとめています。内容に不備等ありましたら連絡お願いします。
【LaTeX: fancyhdr】表紙のヘッダー/フッターを無効化する

Overleafで文書を作成するときに調べたので共有します。
TeXのfancyhdrパッケージを使用した際に表紙のヘッダー/フッターを無効化する書き方の一例を示します。

```:書き方の例

\documentclass{jsarticle}
　･･･
　（各種プリアンブル）
　･･･
\usepackage{fancyhdr}
\pagestyle{fancy} %pagestyleはお好みで
    \lhead{ヘッダ左} %ヘッダ左
    \chead{ヘッダ中央} %ヘッダ中央
    \rhead{ヘッダ右} %ヘッダ右．コンパイルした日付を表示
    \lfoot{フッタ左} %フッタ左
    \cfoot{—\, \thepage \, —} %フッタ中央．ページ番号を表示
    \rfoot{© 著作権} %フッタ右

\begin{document}
\maketitle
\thispagestyle{empty}
　･･･
　（中略）
　･･･
\end{document}
```

重要な部分は `\thispagestyle{empty}` の行です。これを `\maketitle` の直後に書くことで表紙のヘッダー/フッターのスタイルを無効化することができます。当然ですがOverleaf上でも同様に機能します。なお、プリアンブルに `\renewcommand{\headrulewidth}{0pt}` と書いておけば全ページでヘッダーの羅線を消すことができます。

ページの制御は `\newpage` などのコマンドで可能なので、特定のページ（下の例では `aaa` のページ）だけスタイルを無効化することもできます。

```:書き方の例
\begin{document}

\newpage

\thispagestyle{empty}
aaa

\newpage

bbb

\end{document}
```
Excelのマクロ（1行）でメニューを作る

ExcelでVBAを記述しようとして、1行書くたびにコマンドをググルのが面倒臭くありませんか？

日本語で簡単にコードを連想できるように［日本語ローコード］関数を作成ました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93227/463611c1-d90a-b036-12bf-c594eb65e404.png)

上のようなメニューを表示するには、下記のように1行で記述します。

```VBA:Menu.vba
Sub メニュー()
  n = f_メニュー("タイトル", "メニュー1,メニュー2", "選択してください", 0)
End Sub
```
選択したメニュー番号は、n に代入されます。

［f_メニュー］関数の構文は、下記のようにしています。

【構文】　f_メニュー("<タイトル>","<メニュー1>,<メニュー2>,・・・","<メーッセージ>",メニュー初期値)
 【戻り値】選択したメニュー番号。[中止]したときは 0 を返します。

このような関数をまとめたのが［日本語ローコードYUGE］です。

##日本語ローコードYUGE （マクロ関数）一覧
f_確認
f_クエリー表示
f_クエリー編集
f_シート印刷
f_シートコピー
f_シート削除
f_シート判定
f_シート追加
f_シート表示
f_シートメニュー
f_条件セル入力
f_条件マスター参照
f_条件日付入力
f_条件年月入力
f_セルコピー
f_選択
f_ダイアログ
f_ファイルオープン
f_ファイル判定
f_ブックオープン判定
f_メニュー

[［日本語ローコード YUGE マニュアル］](https://excel-databace.hatenablog.com/entry/yuge-help)
[［Excel マクロ・VBA 講座］](https://note.com/muramoto1041/m/mc87b8bbc62a4)

##［f_メニュー］関数
```f_メニュー.vba_fuction
Function f_メニュー(qタイトル As String, qメニューリスト As String, qメッセージ As String, qメニュー初期値 As Integer) As Integer
  '
  '【構文】　f_メニュー("<タイトル>","<メニュー1>,<メニュー2>,・・・","<メーッセージ>",メニュー初期値)
  '【戻り値】選択したメニュー番号。[中止]したときは 0 を返します。
  '
  ygSTR1 = qタイトル
  ygSTR2 = qメニューリスト
  ygSTR3 = qメッセージ
  ygInt1 = qメニュー初期値
  Fy_メニュー.Show vbModal
  
  f_メニュー = ygInt1
End Function
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93227/92741f59-4e60-bb7b-17f5-6d75efece2e5.png)

フォームに記述された VBA コードは、上記リンク［日本語ローコード YUGE マニュアル］からダウンロードできます。
JSONをwhile read lineしてjqしててハマった話


JSONの中身の配列を、while read line で逐次処理していて、エラーになりました。

`parse error: Invalid numeric literal at line 1, column 335`

## TL;DR

read に -rオプションを付けたら解決しました。

```bash
while read -r line;do
    : #処理
done
```

原因は、String値の中の`\"`のバックスラッシュが外れてしまっていた為です。
readがバックスラッシュをエスケープ文字として扱う為こうなってしまいます。
-r をつけることで、`\`をただの`\`の文字として変数格納してくれます。

## コード
上手くいかなかったコードです。
AWSCLIのdescribe-stacksからCloudFormationスタック達を逐次処理してやろうとしていた訳です。

```bash
# functions
each_elm_in_array(){
        jq -c '.[]'
}

# main
stacks=$(aws cloudformation \
        describe-stacks \
        --query Stacks \
        --output json
)

echo "$stacks" | each_elm_in_array | while read stack;do
        stack_name=$(echo "$stack" | jq -r .StackName)
        echo "$stack" | jq '.Parameters | map(.ParameterKey + "=" + .ParameterValue)?' > $stack_name.json
done
```
既存のCloudFormationスタックからパラメータを抜き出して、`aws cloudformation deploy`コマンドに渡せるjsonファイルを作ります。
上手くいく方はこちら、つってもreadに-rオプション付けただけ。

```bash
# functions
each_elm_in_array(){
        jq -c '.[]'
}

# main
stacks=$(aws cloudformation \
        $aws_region_option \
        $aws_profile_option \
        describe-stacks \
        --query Stacks \
        --output json
)

echo "$stacks" | each_elm_in_array | while read -r stack;do
        stack_name=$(echo "$stack" | jq -r .StackName)
        echo "$stack" | jq '.Parameters | map(.ParameterKey + "=" + .ParameterValue)?' > $stack_name.json
done

```

## 解説

`each_elm_in_array` は、JSON配列を受け取ることを予期しています。`.[]`で配列の要素を取り出して分解しています、`-c`オプションでその分解した一要素を一行にしている感じです。
あとは、`while read stack`に渡して、１要素（=１行）ずつ処理していってます。

エラーが起きたのは、下から２行目の `echo "$stack" | jq ...` のところでした。
エラーの原因となったJSON文字列を覗いてみると、以下のような部分が、、、
`"Description":"IAM role for serviceaccount "k8s-namespace/external-dns" [created and managed by eksctl]"` ←エラーの時
`"Description":"IAM role for serviceaccount \"k8s-namespace/external-dns\" [created and managed by eksctl]"` ←本来こうなってて欲しかった
文字列の中の`"`は`\"`のようにエスケープされてないといけませんがバックスラッシュが外れていました。これが原因でjqのパースエラーが起こっていた訳です。

あー、どこでエスケープ外れてしまったんだろう。。と思っていたらreadコマンドでstack変数に格納するところでした。
readコマンドは、デフォルトではバックスラッシュをエスケープ文字として解釈するんですね。。。うーんこの仕様って救われる人よりトラブる人の方が多いのでは？

## 所感

shellスクリプトでJSONの中身の配列を逐次処理したいことって結構あるのではないかと思うので、そんな時にはハマりやすいポイントなのでは？と思って投稿しました。sedしてreadに渡してもいいんですけどパイプするコマンド一個増えてなんかそれもなーと思ったので、readのオプションで対処できてよかったですね。
`while read line` する時は基本何も考えず`-r`オプション付けた方がトラブらないで済みそうだなーとも思いました。
laravel with で limit take

laravel で with を使って関連モデルを読み込んだとき、
limit , take で取得数を制限したい場合がある

しかし、普通にやっても動かないので、

https://github.com/staudenmeir/eloquent-eager-limit

を使おう


# インストール

```

composer require staudenmeir/eloquent-eager-limit:"^1.0"

```


```database.php

//以下の箇所をすべて false に変更
'strict' => false,

```


キャッシュを消して有効に

```

php artisan config:clear
php artisan config:cache

```

# 使い方

Autotweet -> Social -> Answer

って感じで関連付けしたとき、
Answerを3件だけ取得したい

```Social.php


class Social extends Model
{
    use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;

    public function answer()
    {
        return $this->hasMany('App\Answer');
    }


```

```Answer.php

class Answer extends Model
{

    use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;

```

こんな感じ

使い方は

```HogeController.php

$tweet = Autotweet::query()//単数形 User

    ->with([
        'social' => function ($q)  {
            $q->with(
                [
                    'answer' => function ($q2)  {
                        $q2->orderBy('id','DESC')->take(3);//3件のみ取得
                    },
                ]
            );
        },
    ])

    ->get();

```


で使えます。



# 注意点

・database.php の strict を変更すること
・関連付けするモデル（この場合はSocial.phpとAnswer.php）両方に
`use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;`
を設定することが大事
プロエンジニアの教え方を未来の私の為にメモっておく

## この記事を書いた経緯
私は現在エンジニアスクールに通っています。
プロエンジニア講師に個別で補習をしてもらい、何週間も悩んだ機能がやっと実装できました。
動いたときの喜びが今でも忘れられません。
答えをすぐに教えるような教え方ではなかったため2時間かかりましたが、とても丁寧に実装まで導いてくださいました。

（気が早いですが）自分がいつか誰かに指導する立場になったとき、この記事を見返そうと思い、投稿させていただきます。

## 質問した人
- 自分のできる限りググりつくしている。
- 今回の質問は(Java)SpringSecurityについて。登録済のId,Passを入力してもloginできない状態だった。

## 事前準備
- コードをもらっておき、予め何が問題だったか予想しておく。



## 講師の教え方

#####1. 何がしたいのか、自分の言葉で全体のコード説明させる。
 - 最後まで喋らせる。口を挟まない。 
  
#####2. 何が問題だと思うのか、自分の言葉で説明させる。  

- 何でそう思うのか根拠を聞く。 
- デバック等で確認したか聞く。
- 気になるポイントがあれば、どんな意図でそうしたのか聞く。
   
#####3. 実際に動かしてみて、動かないことを一緒に見る。
  - どこまで動いていると思うか聞く。
  - デバックを一緒にしてみた上で、またどこまで動いていると思うかまた聞く。
  
#####4. どこまで値が渡させているか場所が判明したら、解決方法を探る。
  - 質問者が解決する上で分かりずらいものを付けていたら一旦外す。（今回だと独自のlogin画面。一旦設定をデフォルトにしておく。）
  - 必要なところまで値が届くように、細かくデバック＆実行していく。
  - エラー、例外が出たら何だと思うか読ませる。 
  - 自分で調べさせて、予想を言わせてから解説する。
     - 調べさせても予想が出ない場合は、ヒントを出してみる。
 
#####5. あとは少しずつひも解いていく。

#####6. 4で外したコードを戻して、実装してみる。

#####7. 実装できたら「いえーい！」と一緒に喜んであげる。

#####8. 最後に「こうしてもいいよ」「こうしたらもっといいかも」を伝える。他に理解できなかったことはないか聞く。

## まとめ
- 一緒に喜んであげる。
- 焦らせない、せかさない、ゆったりする。
- 「おしい」と言ってあげる。（全然見当違いじゃないと伝えると安心してもらえる）
- 自分の考えを言わせる、調べさせる、また考えを言わせる。
- 付属する知識も一緒に伝える。

## 最後に
今回私は悩んで調べまくってもできなかった機能が実装できて、本当に嬉しくて、またプログラミングの勉強を頑張ろうと思いました。
そう思ったのは、自分の力で実装までできるように丁寧に導いて下さったからだと思います。
実務で2時間丁寧に教えて頂けることはそうそうないと思います。
解決までのプロセスが学べるので、未経験、新人に一度だけでもいいので、こんな体験に付き合ってあげるのは良いのではないでしょうか。

## 因みにSpringSecurityでログインできなかった原因
- 独自のuserを作っていなかった。（作る意味が分かっていなかった）
- 独自のlogin.htmlがタイムリーフになっていなかったので、入力した値を渡せていなかった。 


　　
**最後まで読んでいただきまして、ありがとうございました。**
小ネタ：複数の位置番号を指定して、リストの中身を取る｜Power Query

ふと気づいたら、そのような記法や既定の関数がないようなので、一つの解法を残しておきます。

##結論

```
let Source ={73,82,77,56,21,56,91,44,98,27,29,47,63,47,98,3,86,100,68,31}
in  List.Accumulate(
       {4,5,10,13}, //位置を指定するリスト。0始まりで、4,5,10,13番目を取りたい。
       {}, //初項
       (x,y)=>x & { Source{y} } //1周目は初項と4、2周目は{4}と5･･･というように実行される。
    ) 
```
![無題2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370992/c900f325-77b5-9871-2847-b0540f232a47.png)

##解説
ある`list`について、特定の位置の値だけ欲しいというとき、1個なら、こういう記法で取れます。0始まりで数えます。


```pq:普通に位置一個を指定する書き方
let Source ={73,82,77,56,21,56,91,44,98,27,29,47,63,47,98,3,86,100,68,31}
in  Source{2}  //0始まりで2番目を指定。77が返る。
```

ただ、それが例えば、4,5,10,13番目だけが欲しいというような場合。こんな記法は許されません。

```pq:エラーになる例
let Source ={73,82,77,56,21,56,91,44,98,27,29,47,63,47,98,3,86,100,68,31}
in  Source{4,5,10,13}  //エラーになる。
```
なので、結論に書いたようなコードで取りたい番号のリストを作り、取ってはくっつけてやることになります。
List.Accumulate大事ですね。

もちろん、地道に書いてもよいのですが、量や用途によっては取れない方法です。

```pq:個人的にはやりたくない
let Source ={73,82,77,56,21,56,91,44,98,27,29,47,63,47,98,3,86,100,68,31}
in  Source{4} & Source{5} & Source{10} & Source{13}
```


##参考
list自体についての基礎
https://docs.microsoft.com/ja-jp/powerquery-m/m-spec-values#list
List.Accumulate関数
https://docs.microsoft.com/ja-jp/powerquery-m/list-accumulate
flickr APIで富士山の画像を自動取得

Udemyで[【画像判定AIアプリ開発・パート2】Django・TensorFlow・転移学習による高精度AIアプリ開発](https://www.udemy.com/course/django-ai-app/learn/lecture/14733746)を受講した。オリジナルの機械学習プログラムを作る際に、インターネット上から画像を取得するのが非常に手間だと感じていたので、画像取得自動化の方法を記録しておく。

# flicker APIのKey取得

flickerのホームページ
 → フッターのナビゲーションバーから**Developers**を選択 
 → 画面上部から**API**を選択 
 → Getting Startedの①にある**Request an API key**を選択 
 → ①のGet your API keyにある**Request an API key**を選択 
 → 商用利用ではないので、**APPLY FOR A NON-COMMERCIAL KEY**を選択 
 → 作りたいアプリケーションの名前、アプリケーションの説明を入力
 → チェックボックスを埋めて、**SUBMIT**を選択 
 → KeyとSecretの取得完了！

![flicker_key.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/854965/93c62e64-1a25-c80e-fddb-e8fcc2467f6a.png)

# 画像をダウンロードするPythonファイル

これから目的の画像を取得する。

flickr APIのパッケージを仮想環境内にインストールする。私はAnaconda仮想環境を使っており、パッケージのインストールには`pip install`ではなく`conda install`を使うようにしているが、Anaconda Cloudで「flickrapi」で検索しても情報がほとんどなかったため、`pip install`を使った。（それっぽいパッケージもあるにはあるが、300ダウンロードにも満たないものだったので避けた。）

```
$ pip install flickrapi
```

今回は`download.py`というファイルで富士山の画像のダウンロードを自動でおこなう。`download.py`と同じディレクトリに`data`というディレクトリを作成し、さらにその内部に`mt.fuji`というディレクトリを作成した。この`mt.fuji`の中に画像をダウンロードする。ソースコードは以下の通りである。

```python:
from flickrapi import FlickrAPI
from urllib.request import urlretrieve
import os, time, sys

key ="**************************"  # 先ほど取得したKeyをコピー&ペースト
secret = "****************"  # 先ほど取得したSecretをコピー&ペースト
wait_time = 1

keyword = sys.argv[1]
savedir = "./data/" + keyword

flickr = FlickrAPI(key, secret, format='parsed-json')
result = flickr.photos.search(
    text = keyword,
    per_page = 400,
    media = 'photos',
    sort = 'relevance',
    extras = 'url_q, license',
    )

photos = result['photos']

for i, photo in enumerate(photos['photo']):
    url_q = photo['url_q']
    filepath = savedir + '/' + photo['id'] + '.jpg'
    if os.path.exists(filepath):
        continue
    urlretrieve(url_q, filepath)
    time.sleep(wait_time)
```

このように書いたうえでターミナルで

```
$ python download.py mt.fuji
```

と入力すると画像のダウンロードが始まる。数分後、`mt.fuji`の中身を確認すると、以下のように画像がダウンロードされている。

![image_download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/854965/ffe8ad13-ab6e-9632-e2ba-4bcc37e27623.png)

これで、画像を手作業でダウンロードするという手間を大幅に省くことができた。しかしこのままでは関係ない画像も多く混じっているため、もっと工夫が必要である。

* 【画像判定AIアプリ開発・パート2】Django・TensorFlow・転移学習による高精度AIアプリ開発
https://www.udemy.com/course/django-ai-app/learn/lecture/14733746
rails generate scaffoldをしたときに打ち間違いをしてしまったらどうするか

#はじめに
Railsチュートリアル第2章で/usersが開けなかったので、原因を調べたら、scaffoldを作成したときに打ち間違いをしていたためでした。

#エラーの原因
```
rails generate scaffold Usser name:string email:string
```
`User`と打ちたかったところを`Usser`と打ち間違いをしていますね。


#エラー解決までの道のり
打ち間違えに気づいたときには、すでに`rails db:migrate`を実行していたため、まずは変更を取り消しからはじめました。

```
rails db:rollback
```
上記のコマンドを実行すると、以下の表示がターミナルに表示されます。

```
== 20210123005915 CreateUssers: reverting =====================================
-- drop_table(:ussers)
   -> 0.0047s
== 20210123005915 CreateUssers: reverted (0.0122s) ============================
```
そして、scaffoldを削除します。

```
rails destroy scaffold Usser
```
これで`rails generate scaffold Usser name:string email:string`を実行する前まで戻ったはずなので、もう一度`rails generate scaffold`をします。今度はうち間違えないように慎重に。

```
rails generate scaffold User name:string email:string
```
忘れずに`migrate`します。

```
rails db:migrate
== 20210123041232 CreateUsers: migrating ======================================
-- create_table(:users)
   -> 0.0116s
== 20210123041232 CreateUsers: migrated (0.0129s) =============================
```

無事に表示されました！

#さいごに
打ち間違えって怖いですね。一文字でも違っていればアウトですもんね。
でもまぁ確かに、私の名前は「え"ま"」でも「え"も」でもなく「え"む"」ですもんね。
さて、Usserってなんと読むのでしょう。「ゆーずずずぁー」って感じでしょうか。どうでもええがな。


#参考にした記事
* [【Rails Girls参加者向け】scaffold作成時にカラム名（属性名）を打ち間違えた場合の修正手順](https://qiita.com/jnchito/items/ab17ed02c82f86077022)
【Kubernetes】初心者のkubectlメモ

メモを残そうと思いつつ、まとまってかけていないので、もう雑多なままですが、とりあえず思い付きを書きます。
そのうち整理したい。

### クラスタと契約

```
$ gcloud container clusters list
$ gcloud container clusters get-credentials $NAME --zone=$ZONE --project $PROJECT_ID
```

kubectl get .. で設定を見る。詳細は kubectl describe .... で見る。

### 稼働状況

Deploy した内容を調べる。kubectl apply -y deployment.yaml などをした後や、GCPのcloud build が通った後にみる。

```
$ kubectl get deployments
NAME        READY   UP-TO-DATE   AVAILABLE   AGE
hello-app   3/3     3            3           94s
```

### IPアドレスとか

IPアドレス見るときは

```
$ kubectl get pod -o wide
```

としています。サービス（ルータみたいなの？）については、

```
$ kubectl get service <SERVICE NAME>
NAME           TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
<SERVICE NAME> LoadBalancer   10.79.247.115   10.146.0.9    80:32456/TCP   3m14s
```

```
$ kubectl describe service <SERVICE NAME>
```

### CPUの使用率を見る: top

top も使える。

```shell 

$ kubectl top node
$ kubectl top pod
```

### HorizontalPodAutoscalerの設定

CPU使用率で制御の設定をかけられる。
Deployment について設定するみたい。
動作状態は

```
$ kubectl get HorizonalPodAutoScaler
```

で見れる。describe も。現在の使用例は ```kubectl top``` で見れる。

- 参考 https://qiita.com/sheepland/items/37ea0b77df9a4b4c9d80


# デバッグするとき

### Pod をのぞく

稼働中のpod に入ってい調べる。というときのワークフロー

```SHELL
$ kubectl get pods
```

でpodを調べて入る。Podではubuntuをベースにしたコンテナが実行されている。

```
$ kubectl exec -it <POD_NAME> -- /bin/bash
```

ファイルのコピーもできる。

```
$ kubectl cp <POD_NAME>:<file_path> <local-filename>
```



### Tutorial より

- [Label and Selectors](https://kubernetes.io/ja/docs/concepts/overview/working-with-objects/labels/)
- [外部IPで接続](https://kubernetes.io/ja/docs/tutorials/stateless-application/expose-external-ip-address/)


### Docker にkubectl 含める

ubuntu:18.04 をbase にしてcontainer を作るとき、下記をDockerfile に書いたら、container 内でkubectl が使えた。

```Dockerfile

RUN apt-get update  -y && apt-get install -y apt-transport-https gnupg2 curl && \
  curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - && \
  echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | tee -a /etc/apt/sources.list.d/kubernetes.list && \
  apt update -y && apt install kubectl -
```

(2021/01/23)

## 更新記録

- 2021/01/23 とりあえず投稿してみた。
- 2021/02/08 に 「Docker にkubectl 含める」追加。
rails generate scaffoldのコマンドを間違えたとき

Railsチュートリアル第2章で`rails generate scaffold`のコマンドを間違えてしまって、戻し方が分からなかったのでメモ。

以下のコマンドで削除できます。

```
rails destroy scaffold [name]
```

参考：[scaffoldで作成したファイルを全削除 - たまめも(tech)](https://tamamemo.hatenablog.com/entry/20120113/1326435969)


前回（[Railsチュートリアルでつまずいたところ（第1章） - Qiita](https://qiita.com/y_horikiri/items/5727597381d3241178ab)）「第1章」って付けたばっかりに第2章も書かなきゃいけないような気になったけど、あんまりつまずくところがありませんでした。よくできたチュートリアルだ。
第3章以降は何かあればトピックごとに書こうと思います。
【PHP】Docker環境にphpMyadminを導入する

# 手順
docker-compose.ymlにphpMyadominのコンテナを追記します。

```yml:docker-compose.yml

#docker-compose.ymlのバージョン
version: "3.8"
#docker volumeの設定
volumes:
  docker-volume:

#services以下に各コンテナの設定を書く
services:
  #Webサーバーのコンテナ
  web:
    image: nginx:1.18
    ports:
      - "8000:80"
    depends_on:
      - app
    volumes:
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
      - .:/var/www/html
  #アプリケーションのコンテナ
  app:
    build: ./docker/php
    volumes:
      - .:/var/www/html
  #データベースのコンテナ
  db:
    image: mysql:5.7
    ports:
      - "3306:3306"
    environment:
      MYSQL_DATABASE: db_name
      MYSQL_USER: db_user
      MYSQL_PASSWORD: db_password
      MYSQL_ROOT_PASSWORD: root
      TZ: "Asia/Tokyo"
    volumes:
      - docker-volume:/var/lib/mysql
  # phpMyadominのコンテナ作成
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    depends_on:
      - db
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOSTS=db
      - PMA_USER=db_user
      - PMA_PASSWORD=db_password
    ports:
      - "8080:80"
    volumes:
      - ./docker/phpmyadmin/sessions:/sessions
```

コードの下部にある`# phpMyadominのコンテナ作成`からが追記する箇所です。
portsを8080に設定しているので、`localhost:8080`でphpmyadminの管理画面にアクセスできるように設定しています。
また、volumesにある`./docker/phpmyadmin/sessions:/sessions`ではセッション情報をボリュームに設定して永続化するようにします。





# 補足
参考までに作ってみた環境
↓

https://github.com/yuyaamano23/Laravel_Docker_practice/tree/github-open


<br>
<br>

ちなみに僕は以下の記事を参考にphp+mysql+nginxの環境を構築しました。
[絶対に失敗しないDockerでLaravel+Vueの実行環境（LEMP環境）を構築する方法〜前編〜](https://qiita.com/shimotaroo/items/29f7878b01ee4b99b951)
[絶対に失敗しないDockerでLaravel6.8+Vueの実行環境（LEMP環境）を構築する方法〜後編〜](https://qiita.com/shimotaroo/items/679104b7e00dd9f89907)
[Docker Composeでphpmyadminを導入する](https://zukucode.com/2019/06/docker-compose-phpmyadmin.html)

各々構築したDocker環境のプロジェクトにあるdocker-compose.ymlnに追記していただければ良いと思います。
初心者　初めてのWEBアプリ（FASTAPI)　

初めてWEBアプリを開発しています。
FASTAPIをお薦めされ、このフレームワークを使用していますが、なかなか参考資料が少なく開発難航中です。(笑)

現在の困りごと：
トレーニングの計画や実施事項をまとめたスポーツのコンデションプランを視覚化できるアプリケーションを作っています。
ユーザーをスポーツチームでお互いのプランやトレーニング内容を確認できるようにアプリ内でユーザーをグループ化できるようにしたいのですが、どのようにコードを書くかに困っています。
グループ機能を組み込むには、どのようなロジックで書くか模索中！

記事として書いてますが、何か参考にグループ機能についてコメントに書いていただけますと嬉しいです！
絶賛、猛勉強中！！
AlphaGo概要解説

#AlphaGOアルゴリズム備忘録

##AlphaGOに使用する4つのアルゴリズム解説
__①SLポリシーネットワーク__
畳み込みニューラルネットワーク(CNN)によって次の一手を決定します。
SLは教師あり学習(supervised learning)の略

プロ棋士の棋譜よりデータを取得し、それを学習させます。
入力データ：盤面
CNN
出力データ：次の一手

__②モンテカルロ木探査__
先読み機能のために実装
ある盤面から石を打ち合い、盤面が進むシミュレーションを行うためのアルゴリズムです。

③__RLポリシーネットワーク__
自己対戦の強化学習アルゴリズム
バリューネットワークの教師データ生成に使用します。

RLは強化学習(reinforcement learning)の略

__④バリューネットワーク__
ある盤面から「勝てる確率」を算出する評価関数

RLポリシーネットワークより、プレイアウト(コンピュータ同士の自己対局)を繰り返し、
ある盤面から始めた時の勝率を自己対局の勝率により決定します。

例)盤面Aから黒が先に打つ状況で、100回対局を行いました。
黒は100対局中90勝10敗しました。
盤面Aの勝率は90%です。

##AlphaGO学習アルゴリズム
①：プロ棋士の棋譜(過去の対戦した記録)より、入力データ：盤面、出力データ：次の一手をCNNを使用し、学習させます。結果、「ある盤面に対して、次の一手を指す」SLポリシーネットワークを構築します。

②：RLポリシーネットワークを使用し、SLポリシーネットワークのアルゴリズムで、コンピュータ同士の自己対局を行います。ある盤面に対して、終局までシミュレーションを何度も行います。そして、ある盤面に対しての勝率を導きます。

③：②の結果から、入力データ：盤面、出力データ：勝率をCNNで学習させます。結果、バリューネットワーク(ある盤面に対しての勝率を導くことができるアルゴリズム)を構築することができます。

##AlphaGO実装アルゴリズム
①：モンテカルロ木探査を行います。探査する過程で、バリューネットワークを使用し、勝率を導きます。勝率の高い盤面は深く、勝率の低い盤面は浅く、探査します。

②：探査が終了したら、SLポリシーネットワークより、次の一手を決定します。

#参考文献
[1] D. Silver et al., "Mastering the game of Go with deep neural networks and tree search," nature, Vol. 529, No. 7587, pp. 484-489, 2016.

[2]AlphaGoを模したオセロAIを作る(1): SLポリシーネットワーク - Qiita
Python3: Let's Encrypt の証明書を使ったブローカーに接続

こちらで作成したブローカーに接続する方法です。
[Mosquitto で Let's Encrypt の証明書を使う](https://qiita.com/ekzemplaro/items/d2afb5d421c7d4d457c2)

```text:.env
HOST=abc.example.com
TOPIC=sensors/topic_1
```

```py:publish_ca.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#	publish_ca.py
#
#					Jan/23/2021
#
# ------------------------------------------------------------------
import	sys
import	os
from dotenv import load_dotenv
from time import sleep
import paho.mqtt.client as mqtt

# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
dotenv_path = '.env'
load_dotenv(dotenv_path)
host = os.environ.get("HOST")
topic = os.environ.get("TOPIC")

port = 8883

client = mqtt.Client(protocol=mqtt.MQTTv311)
client.tls_set('/etc/ssl/certs/ca-certificates.crt')

client.connect(host, port=port, keepalive=60)

client.publish(topic, 'Good Afternoon')
sleep(0.5)
client.publish(topic, 'こんにちは')

client.disconnect()

sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

```py:subscribe_ca.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#	subscribe_ca.py
#
#					Jan/23/2021
#
# ------------------------------------------------------------------
import	sys
import	os
from dotenv import load_dotenv
from time import sleep
import paho.mqtt.client as mqtt

# ------------------------------------------------------------------
def on_connect(client, userdata, flags, respons_code):
	print('status {0}'.format(respons_code))

	client.subscribe(topic)

def on_message(client, userdata, msg):
	print(msg.topic + ' ' + str(msg.payload,'utf-8'))

# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")

dotenv_path = '.env'
load_dotenv(dotenv_path)
host = os.environ.get("HOST")
topic = os.environ.get("TOPIC")
port = 8883

client = mqtt.Client(protocol=mqtt.MQTTv311)
client.tls_set('/etc/ssl/certs/ca-certificates.crt')

client.on_connect = on_connect
client.on_message = on_message

client.connect(host, port=port, keepalive=60)

client.loop_forever()

sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```
Gormの1.9と1.20で失敗したお話

#最初に
2021年1月23日時点で、GORMの最新版はv1.20.11ですが、Qiitaや巷の記事はv1.9.xの物が多く(特に日本語)
公式ドキュメントは、基本v1.20がヒットするのでGorm初心者の私は混乱したというお話です。

##バージョンはよく確認しよう
当たり前のことですが、パッケージのバージョンと参考記事のバージョンはよく確認しましょう。

##GORMのバージョン

```
v1.9.x系
import (
  "github.com/jinzhu/gorm"
   _ "github.com/jinzhu/gorm/dialects/mysql"

)
```

```
v1.20.11
import (
  "gorm.io/gorm"
  "gorm.io/driver/mysql"
)
```
1.9系と1.20系でインポートするパッケージが異なります。
ネットの記事をそのままに、「go get github.com/jinzhu/gorm」すると1.9系がインストールされます。

## 変更点
ほかに記事を上げてくださっている方がいらっしゃるので、すべては書きませんが
私が影響を受けたのは、
　・「RecordNotFound」がなくなったこと
　・DB接続の書き方が変わったこと
　・バッチインサートができるようになったこと！(めっちゃうれしい)
がまず影響を受けました。

##まとめ
Goのパッケージは、現在も開発が活発で進化していますが、
そのぶん技術系記事も更新前の情報がひっかかりやすいです。
基本的なことでお恥ずかしい限りですが、
久しぶりに引っかかったので初心を忘れないために記事にしました。

ありがとうございました。
GitHub Actionsでyarnのキャッシュを利用してCI高速化

コメントいただいた通り、2021年7月にactions/setup-nodeがキャッシュ機能を実装したので、そちらを使う方が良さそうです。

https://github.blog/changelog/2021-07-02-github-actions-setup-node-now-supports-dependency-caching/

# 目的
GitHub Actionsのワークフローの中でyarn installしている場合に、毎度時間がかかっているのを、公式のキャッシュ機能(actions/cache@v2)を使って高速化したい。

https://github.com/actions/cache
https://github.com/actions/cache/blob/main/examples.md#node---yarn

# 公式に記載されているymlの書き方

```.github/workflows/*.yml
on:
  {トリガー}:

jobs:
  <job_id>:
    name: <job_name>
    runs-on: ubuntu-latest

    steps:
      - name: Get yarn cache directory path
        id: yarn-cache-dir-path
        run: echo "::set-output name=dir::$(yarn cache dir)"

      - uses: actions/cache@v2
        id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
        with:
          path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
          key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
          restore-keys: |
            ${{ runner.os }}-yarn-
      
      - name: Install Dependencies
        if: steps.yarn-cache.outputs.cache-hit != 'true'
        run: /install.sh # ここでyarn installを実行

      # 以下は説明のために付け足し
      - name: Build
        run: yarn run build
```

# Actionを実行すると
`actions/cache@v2`ステップのログには以下のように出力される。
何やらキャッシュがrestoreされているように見える。

```
Run actions/cache@v2
Received 168279738 of 180862650 (93.0%), 160.5 MBs/sec
Received 180862650 of 180862650 (100.0%), 145.7 MBs/sec
Cache Size: ~172 MB (180862650 B)
/usr/bin/tar --use-compress-program zstd -d -xf /home/runner/work/_temp/5e202deb-23fd-4213-a874-5021dc5c81f4/cache.tzst -P -C /home/runner/work/myproject/myproject
Cache restored from key: Linux-yarn-950b3c9910c22cfae7c86bc34041990748e7bee522be954b49cf1c409649ba29
```

そして、`if: steps.yarn-cache.outputs.cache-hit != 'true'`によって、キャッシュが存在する場合yarn installがスキップされている。

が、後続のyarn buildでエラーとなる。以下の例はAngularのngコマンドがないというエラー。
つまりキャッシュのrestoreがうまくできていない。

```
$ ng build --configuration=development --aot
/bin/sh: 1: ng: not found
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
error Command failed with exit code 127.
Error: Process completed with exit code 127.
```

# 解決方法
`if: steps.yarn-cache.outputs.cache-hit != 'true'` を削除して、yarnに`--prefer-offline`オプションをつければ良い。
これはローカルキャッシュがある場合はそれを使い、なければネットワークからダウンロードするというオプション。

```.github/workflows/*.yml
      - name: Install Dependencies
        # if: steps.yarn-cache.outputs.cache-hit != 'true'
        run: yarn install --prefer-offline
```



参考：https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions/62244232#62244232
3Dあみだくじ（物理）

例によって、やってみたかっただけ

<p class="codepen" data-height="410" data-theme-id="light" data-default-tab="result" data-user="kob58im" data-slug-hash="jOMoYOm" style="height: 410px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="3D ladder lottery by using cannon.js">
  <span>See the Pen <a href="https://codepen.io/kob58im/pen/jOMoYOm">
  3D ladder lottery by using cannon.js</a> by kob58im (<a href="https://codepen.io/kob58im">@kob58im</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

# 追加

<p class="codepen" data-height="410" data-theme-id="light" data-default-tab="result" data-user="kob58im" data-slug-hash="mdrYLed" style="height: 410px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="3D ladder lottery #2 by using cannon.js">
  <span>See the Pen <a href="https://codepen.io/kob58im/pen/mdrYLed">
  3D ladder lottery #2 by using cannon.js</a> by kob58im (<a href="https://codepen.io/kob58im">@kob58im</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

# 反省点
作り始めたときのカメラの視点配置がよくなく、奥行きがx座標で、座標の正負方向も直感に反している。。。
我ながらややこしすぎる。。

# 備忘録

## 透過

`MeshPhongMaterial`じゃなくてもいいかもしれない。

```js:透過

  new THREE.MeshPhongMaterial({
    transparent: true,
    opacity: 0.3,
    color: 0x99ff99
  });
```

## ボールの順次投入

`scene.add`と`world.add`するタイミングをずらす。