OmniAICreator/Qiita-1.07M huggingface dataset:
強化学習ゼミ記録【森村哲郎】Chapter2

# はじめに
2019年から強化学習ゼミを実施しています。ゼミで議論になった部分について記録します。

# 使用している教科書
- [強化学習 著：森村哲郎](http://bookclub.kodansha.co.jp/product?item=0000275420)

# ディスカッション
## maxの意味
(2.2)式では初期状態に依存して$\boldsymbol{\pi}$が決まっても良い。
つまり、$s_1\in\mathcal S$に対して$\boldsymbol{\pi_1}$、$s_2\in\mathcal S$に対して$\boldsymbol{\pi_2}$、、、となってよい、という式である。

```math
\begin{align}
V^\ast(s_1) &= V^{\boldsymbol{\pi_1}}(s_1) \\
V^\ast(s_2) &= V^{\boldsymbol{\pi_2}}(s_2) \\
...&\\
V^\ast(s_N) &= V^{\boldsymbol{\pi_N}}(s_N)
\end{align}
```
後に任意の初期状態について定常な決定的方策がユニークに最適方策として求められることが明かされます。

## maxの分配
(2.4)式と(2.5)式の間にある式について。

```math
\begin{align}
&\max_{\boldsymbol{\pi}\in \boldsymbol{\Pi^M}}\mathbb{E}^\boldsymbol{\pi}[g(s, A_0) + \gamma C_1|S_0 = s] \\
=&\max_{\pi_0\in\Pi}\mathbb{E}^{\pi_0}[g(s,A_0)+\gamma \max_{\{\pi_1,\pi_2,...\}\in\boldsymbol{\Pi^M}}\mathbb{E}^{\{\pi_1,\pi_2,...\}}[C_1|S_1\sim p_T(\cdot|s,A_0)]|S_0=s]
\end{align}
```
まず、maxの順序は任意に取れる。通常の関数のmax、

```math
\max_{x, y} f(x, y) = \max_x f(x, y(x))
```
のように$\pi$のmaxも計算される。

```math
\max_{\boldsymbol{\pi}} f(\boldsymbol{\pi}) = \max_{\pi_0} f(\pi_0, \pi_1(\pi_0), \pi_2(\pi_0), ...)
```
上記の意味で、maxを分配できる。

```math
\begin{align}
\max_{\boldsymbol{\pi}} f(\boldsymbol{\pi}) =& \max_{{\pi_0}} \max_{{\pi_1}}\max_{{\pi_2}}...f(\boldsymbol{\pi})\\
=&\max_{{\pi_0}} \max_{{\pi_1}}f(\pi_0, \pi_1, \pi_2(\pi_0,\pi_1), \pi_3(\pi_0,\pi_1, \pi_2), ...)\\
=&\max_{{\pi_0}} f(\pi_0, \pi_1(\pi_0), \pi_2(\pi_0,\pi_1), \pi_3(\pi_0,\pi_1, \pi_2), ...)
\end{align}
```

## 確率方策から決定的方策への転換
(2.5)式の直前の式から(2.5)式への変形について。

```math
\begin{align}
V^\ast(s) =& \max_{\pi_0\in\Pi}\sum_{a_0\in \mathcal A}\pi_0(a_0|s)\Big( g(s,a_0)+\gamma\sum_{s_1\in\mathcal S}p_T(s_1|s,a_0)V^\ast(s_1) \Big) \\
=& \max_{a\in \mathcal A}\Big( g(s,a)+\gamma\sum_{s'\in\mathcal S}p_T(s'|s,a)V^\ast(s') \Big)
\end{align}
```
この式変形で方策$\pi_0$が消えている。下記の計算で説明する。
maxは値を最大化する分布の選択を、和は$a_0$に対する積分に相当する。

```math
\begin{align}
\max_{p\in \boldsymbol{P}} \int {\mathrm d}x p(x)f(x) = \max_{a}\int {\mathrm d}x \delta(x-a)f(x)
\end{align}
```
$f(x)$が最大になるところに$p(x)$が集中するときが一番値が大きくなるので、分布は$\delta$関数になり、引数は$f$が最大になるところになる。分布が$\delta$関数になるということは決定的方策になることを示している。

## 最適方策の初期値非依存性
任意の初期状態について定常な決定的方策がユニークに最適方策として求められる、という点について、どの段階で任意の初期状態について成り立つことが示されたのか？
→命題2.4bのベルマン期待方程式の解の初期値非依存性から受け継がれている。

## 最適方策の存在性と必要十分条件
命題2.7の(2.28)式を実装で確かめるときはどうすれば良いのか？
→方策反復法（アルゴリズム2.2）では4.の収束判定で収束を確かめたあと、2.の連立方程式を解いて、$V^{\pi^d}$が不変となることを確かめれば良い。価値反復法（アルゴリズム2.1）では3.の収束判定で求めた$v(s)$に対して、$\pi^d_{v'}$を使用した$B_\pi$を作用させて不変であることを確かめればよい。

## 複数のアクション
アルゴリズム2.1の3.の$\mathrm{argmax}_{a\in \mathcal A}$で同一の最大値になる複数の$a$が見つかったらどうする？
→最適方策は複数あった、ということ？（結論つかず）

# おわりに
数学的な部分が色々省略されがちな強化学習ですが、この教科書はかなり厳密な議論がされているのでワクワクです。
UIScrollViewのスクロール量を利用した昇降ViewController

今年もiOSDCでモチベーションがすこし上がったので、便利そうなUIサンプルを作ってみました。
写真を使った検索などでよく見られるUIですね。

## プレビュー
![sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8920/397872c6-3a08-8a6a-b3da-72db64cab7e2.gif)

## ポイント
* addChildでchildViewControllerとして表示しています。
* 上下バウンス効果からもわかるようにスクロールの力だけで昇降させています。そのため一度上に上げてからスクロールさせるという２ステップジェスチャーが不要です。
* UIScrollViewDelegateにさえ対応してさえいれば適応できるのでTableViewやCollectionView, WebViewなどにも応用できます。

:octocat: [ShingoFukuyama/LiftableScrollViewController.swift](https://gist.github.com/ShingoFukuyama/fb326a6d82c8329ec5fcaf78d4a22f3d)

UIScrollViewのcontentInsetやCGAffineTransformを組み合わせた全100行くらいのシンプルなコードなので、詳細はgistを覗いてみてください。
Rubyで決して上書きされない最強のメソッドを定義する方法

# 概要

上書きできない魔法みたいな最強メソッドを定義できるぞ！

# 本編

さて、上書きできないメソッド、どうやって定義しようか？
まずは`prepend`かなあ。匿名モジュールも活用しよう。

## prependを使う

```ruby
class Foo
  mod = Module.new
  prepend mod

  mod.module_eval do
    def saikyo
      puts "I'm saikyo!"
    end
  end
end

class Foo
  def saikyo
    puts "You're not!"
  end
end

Foo.new.saikyo # => I'm saikyo!
```

おお、オープンクラスでも上書きできないぞ！
でも、これ継承されたらダメよね。

```ruby
class Bar < Foo
  def saikyo
    puts "You're not!"
  end
end
Bar.new.saikyo # => You're not!
```

げげ、やっぱり！

## 特異メソッドを使う

インスタンスに定義された特異メソッドって優先順位が高かったような気がするから、やってみよう。
いちいちインスタンス化したあとにメソッド定義をするのは面倒だから…そうだ、イニシャライザでやっちゃえ！

```ruby
class Foo
  def initialize
    instance_eval do
      def saikyo
        puts "I'm saikyo!"
      end
    end
  end
end

class Bar < Foo
  def saikyo
    puts "You're not!"
  end
end

Bar.new.saikyo # => I'm saikyo!
```

勝った、勝ったぞ!
しかし、これだと同じトリックを子クラスでやられると…

```ruby
class Foo
  def initialize
    instance_eval do
      def saikyo
        puts "I'm saikyo!"
      end
    end
  end
end

class Bar < Foo
  def initialize
    instance_eval do
      def saikyo
        puts "You're not!"
      end
    end
  end
end

Bar.new.saikyo # => You're not!
```

## 子クラスでのイニシャライザを叩き潰す

やはりか…
こうなったらメソッド定義に介入するしかないな…
幸い（？）Rubyにはクラス継承とメソッド定義に対するフックを持ってる。これらを駆使すれば、子クラスでのメソッド定義を禁止できるはず！

```ruby
class Foo
  def self.inherited(subclass)
    already_defined = false
    subclass.define_singleton_method(:method_added) do |method_name|
      return if already_defined
      if method_name == :initialize
        already_defined = true
        define_method(method_name) { super() }
      end
    end
  end

  def initialize
    instance_eval do
      def saikyo
        puts "I'm saikyo!"
      end
    end
  end
end

class Bar < Foo
  def initialize
    instance_eval do
      def saikyo
        puts "You're not!"
      end
    end
  end
end

Bar.new.saikyo # => I'm saikyo!
```

解説は諦めた、各自読んでくれ！
でも、ここまでしても、インスタンスに直接定義された特異メソッドを上書きすることはできなかったよ…

# まとめ

こんなRubyハックにマジになっちゃってどうするの
【Rails】renderした後にエラーメッセージが表示されない

# 背景
[現場で使えるRuby on Rails 5 速習実践ガイド](https://amzn.to/2PVowFP)でタスク管理アプリを作成中に、タスク作成に失敗してrenderした後にエラーメッセージが表示されないエラーではまりました。

以下、エラーが起きたときのソースコードの一部です。

```controllers/tasks_controller.rb
  def create
    @task = current_user.tasks.new(task_params)
    
    if @task.save
      redirect_to @task, notice: "タスク「#{@task.name}」を登録しました"
    else
      render :new
    end
  end
```


```views/tasks/new.html.slim
h1 タスクの新規登録

.nav.justify-content-end
  = link_to '一覧', tasks_path, class: 'nav-link'
  
= render partial: 'form', locals: { task: @task }
```

```views/tasks/_form.html.slim
- if task.errors.present?
  ul #error_explanation
    - task.errors.full_messages.each do |message|
      li = message

= form_with model: task, locale: true do |f|
  .form-group
    = f.label :name
    = f.text_field :name, class: 'form-control', id: 'task_name'
  .form-group
    = f.label :description
    = f.text_area :description, rows: 5, class: 'form-control', id: 'task_description'
  = f.submit nil, class: 'btn btn-primary'
```
# 原因と解決策
`form_with`のオプション名を間違えておりました。。。

☓ locale: true
○ local: true

以下のように修正したところ、正常にエラーメッセージが表示されるようになりました。

```views/tasks/_form.html.slim
- if task.errors.present?
  ul #error_explanation
    - task.errors.full_messages.each do |message|
      li = message

= form_with model: task, local: true do |f|
  .form-group
    = f.label :name
    = f.text_field :name, class: 'form-control', id: 'task_name'
  .form-group
    = f.label :description
    = f.text_area :description, rows: 5, class: 'form-control', id: 'task_description'
  = f.submit nil, class: 'btn btn-primary'
```

`form_with`はデフォルトで非同期通信を行うようになっているので、`lacal: true`が正しく設定されていないせいで非同期通信が行われていたことが問題の原因でした。

（form_withのlocalオプションについて：https://railsguides.jp/working_with_javascript_in_rails.html#form-with )

# 余談 : localとlocaleの意味の違い
余談ですが、localとlocaleの意味の違いを調べてみました。これらの意味を明確に理解できていなかったのが、今回のようなミスをおかす原因になったと思うので...

local : 場所の、土地の、(特定の)地方の、地元の、一地方特有の、特定の地方向けの、局所的な、同一区内の、「市内配達」の、市内の（引用：https://ejje.weblio.jp/content/local）

locale : ロケールとは、（物語の）舞台、現場、場所などの意味を持つ英単語で、ITの分野ではシステムやソフトウェアにおける言語や国・地域の設定のことをこのように呼ぶ。（引用：http://e-words.jp/w/%E3%83%AD%E3%82%B1%E3%83%BC%E3%83%AB.html）

上記のとおりです。ロケールは、言語などの設定で使われる単語ということですね。なるほどなるほど。
スタックタイマーの信号について

## 概要
初投稿です。Nyanyanと申します。私はスピードキューブ(ルービックキューブ等立体パズルの速解き)を趣味としていて、ある日、ルービックキューブのタイム計測用のタイマーを作ろうと思いたちました(これには諸事情がありますがそれはTwitterで#nyantimerのタグでも探してみてください)。
キューブ(立体パズル)の大会では計測に一貫して「スタックタイマー」というものを使い、これは信号出力ができます。この信号の内容について日本語の記事を見かけないのでここに書いておきます。なお、本記事は私のタイマー製作の経験に基づいたものであるだけで、どこかのデータシートを見たとかいう話ではないので動作は自己責任でお願いします。
ちなみにこの製作中のタイマーについて気になる方は以下をご覧ください。
https://github.com/Nyanyan/NyanTimer

## 英語が読めるのであれば参照すべきところ
私自身ここを大いに参考としました。
https://github.com/fw42/atmel/tree/master/stackmat

## 信号の概要
概要は以下です。

* 信号はRS232C
* 1200bps
* 一連の信号は約9Hz(111.4ms毎)で送る(諸説あり。この数値は私が測定したもの)
* データビットは8つ(内容はステータス、時刻、チェックサム)
* パリティビットなし
* 終了ビットは~~一つ(LF)~~ ~~2つ(LFCR)(オシロスコープでじっくり調べたら何故か常識の斜め上を行くLFCRでした。嘘だろ…)~~ 2023/09/04追記: 改行コードはCRLFですが、スタックタイマーがリトルエンディアンを採用しているようで、そのためにバイト列はLFが先で、CRが後に来るようです。

## 送る内容
データはASCIIコードで送ります。1文字ずつ解説していきます。

1: ステータスのデータ('I', 'A', 'S', 'L', 'R', 'C', ' ')
2-7: 時刻のデータ(1:23.456なら‘123456’)
8: チェックサム(ASCIIコードで64+タイムの各数字の和, 上の例ならASCII10進で64+21=85='U')
9: ~~CR(ASCIIコード0x0D)~~ LF(ASCIIコード0x0A)
10: ~~LF(ASCIIコード0x0A)~~ CR(ASCIIコード0x0D)

2023/09/04追記: 改行コードはバイトごとに書いてますが、(実態は変わりませんが)CRLFをリトルエンディアンで送っているのだと思います。

1番目、ステータスのデータは、

‘I’: タイマー初期化(リセットされた状態)
‘A’: タイマースタート直前(パッドを手で押さえて、離したらスタートできる状態)
‘ ’: 計測中
‘S’: タイム計測完了
‘L’: 左パッドが覆われている状態
‘R’: 右パッドが覆われている状態
‘C’: 両方のパッドが覆われている状態

ちなみに個人的には'C'はあまり意味を持った情報とは言えないと思っていて、自作のタイマーにも実装していません。

## 注意点
Arduinoなどを念頭にUARTでシリアル通信をする機器でこの信号を実装したいときは信号のHIGHとLOWの反転が必要になります。この際、回路は以下のようにすると良いです。![signal_video.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494375/185fccde-6b2d-5950-173b-9013099a09ca.png)
なお、本家スタックタイマーでは専用ディスプレイにつないだときに信号電圧が1.1V程度まで下がる現象が確認されています。これを再現するためにプルアップ抵抗(R2)は2.2kΩが良いでしょう。

2023/09/04追記: これはUARTの実装上の問題だと思います。ArduinoではアクティブHIGH (ビットが立っているときにHIGHになる) なのですが、スタックタイマーはアクティブLOW (ビットが立っているときにLOWになる) のようです。ですから、何らかのNOT回路を入れて出力すれば良いと思います。ただ、微かな記憶によると、スタックタイマーをディスプレイに繋いだときの信号電圧の変化が結構大事だった気がするので、他の回路で必ずしもうまくいくかというと、わかりません。


## まとめ
今回は需要がなさそうですがスタックタイマーの信号について日本語で書いてみました。
この情報はタイマー本体を作る場合にも、タイマーにつなぐディスプレイを作るのにも使えると思いますので、もし機会があってお役に立てれば幸いです。

2023/09/04追記: 誰得記事だと思って書いたのですが、役に立っているという情報をいただけたので、少しわかりやすく追記しました。大変嬉しいです。
Pythonでリストの取り出し

#introduction
競技プログラミングの問題を解いていた際に用いた方法について書いていきます。
リストの任意の部分を取り出す処理について記述します。

誤っているところがあればコメント等よろしくお願いします。

リストの代入操作について理解が甘かったので、修正いたしました。リストが変数の場合は変数にリストオブジェクトのアドレス値が代入されているので、代入を行う際にはリストオブジェクトのアドレス値を渡しているという理解ができていませんでした。その点を主に修正しました。失礼いたしました。(2020/05/26)

#リストの準備

下記で任意の2次元リストをnumpyを用いて作成しました。

```python:
import numpy as np
array=np.arange(16).reshape((4,4)) #データを準備

>>>array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])
```


##リストの任意部分を取り出す処理

例えば下記に示すような任意の赤丸で囲ったリストを取り出したいとき


<img width="266" alt="スクリーンショット 2019-08-31 15.57.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478601/3d2e77ce-0369-9ea6-b40c-f361b98e1d09.png">




pythonで実装すると以下のようにできると考えました。

```python

div_array=[]
for i in range(1,3):
    tep_array=[]
    for j in range(1,3):
        tep_array.append(array[i][j])
    div_array.append(tep_array)    
print(div_array)    

#div_array=[[5, 6], [9, 10]]
```

ただ、この方法だと記述量も多く、変数をたくさん置く必要があって読みにくいです。
追記：arrayとdiv_arrayが示すリストオブジェクトは異なり、またそれぞれのリスト内のリストのアドレス値も異なっているので、どちらかのリスト内を変更した際にも独立に変更できます。

この読みにくさを解決するために、ndarray型配列であれば、スライスを用いることで実装できます。
（ただしpython のlistでlist[1:3,1:3]と指定するとエラーがおきます。）


```python
div_array=array[1:3,1:3]

>>>div_array([[ 5,  6],
       [ 9, 10]])
```
まず、左側の1:3で行方向を取りだし、
[ 4,  5,  6,  7] と[ 8,  9, 10, 11]の行を取り出します。

次に、右側の1:3で列方向を取り出せます。
よって、[5,6] と[9,10] が取り出せます。

ただ、この場合div_array内のリストのアドレスととarray内のリストのアドレスは同じなので、div_array内をを操作するとarray内のリストの値も変更してしまいます。そこでdiv_array内にarray内のリストとは異なる新たなリストを作成し、そのオブジェクトに元のリストの値をコピーする必要があります。その実装は

```python
div_array=array[1:3,1:3].copy()
```
と記述することで解決できます。

#追記：list内listをprint()するときの豆知識
話が少し逸れますが、list内の要素を順番に出力する際には
以下のようにすることが多いと思います。




```python
for i in div_array:
    print(i)

#[5 6]
#[ 9 10]
```
ただしlistの[]が表示されていると不正解になることもあり、これを防ぐために以下のように実装を試みました。

引数の　end="" にスペースを指定し、5と6 をスペースで分割してその後の空のprint()で次の行に移ることを試みました。


```python
for i in div_array:
    for j in i:
        print(j ,end=" ")
    print()    

>>>5 6 #６、１０の後にスペースが入っている
>>>9 10 #６、１０の後にスペースが入っている
```


ですが、この実装では6と10の後にもスペースが入ってしまい不正解となりました。

これを解決するために以下のようにすれば、簡単に解決することができました。
[ ]を外したいリストの前に*をつけて出力することによって、リスト内リストの各要素を分割して表示することができました。

```python

for i in div_array:
    print(*i)

>>>5 6
>>>9 10
```

#まとめ

今回は2次元リストから任意のリストを取り出す方法と、2次元リストの出力のことに関して述べました。
かなりマニアックな内容ですが使ってみてください。
Windows PowerShell / PowerShell Core 6.0でposh-gitとemacs風キーバインドと色付きlsを導入する

# はじめに

PowerShellを普段使いのgitコンソールにしたくて設定をまとめました。

# PowerShellGet (Windows PowerShellのみ)

posh-gitの1.0系はベータ版なので`Install-Module`コマンドで`-AllowPrerelease`オプションを使います。ですが`PowerShellGet`モジュールのバージョンが古くてオプションがないのでまずは`PowerShellGet`をバージョンアップします。

```powershell
Install-Module -Name PowerShellGet -Scope CurrentUser -AllowClobber -Force
```

- `-Score CurrentUser` : デフォルトのインストール先はシステムなので現在のユーザーにインストールします。
- `-AllowClobber` : 既存コマンドを上書き許可するために指定します。
- `-Force` : 複数バージョンのインストールを許可するために指定します。

コマンド実行後にWindows PowerShellを立ち上げ直してバージョンを確認します。

```powershell
Get-Module -Name PowerShellGet
```

Versionカラムが2系なら正しくインストールされています。
現在の最新版は[PowerShellGet 2.2.3](https://www.powershellgallery.com/packages/PowerShellGet/2.2.3)です。

# posh-git

[dahlbyk/posh-git](https://github.com/dahlbyk/posh-git)はgit-prompt.shと同じようにPowerShellのプロンプトにgitリポジトリの情報を表示するモジュールです。

```powershell
Install-Module -Name posh-git -Scope CurrentUser -AllowPrerelease
```

- `-AllowPrerelease` : プレリリース版を使うので指定します。

コマンド実行後にモジュールをインポートします。

```powershell
Import-Module posh-git
```

この後にgitリポジトリに移動して以下のようなプロンプトになれば正しくインストールされています。

![posh-prompt](https://raw.githubusercontent.com/wiki/dahlbyk/posh-git/images/PromptDefault.png)

# emacs風キーバインド

[PSReadLine](https://docs.microsoft.com/ja-jp/PowerShell/module/psreadline/)の`Set-PSReadlineOption`でemacs風キーバインドに変更できます。

```powershell
Set-PSReadlineOption -EditMode Emacs
```

# 色付きls

PowerShellのls(Get-ChildItem)は白一色ですが、[joonro/Get-ChildItemColor](https://github.com/joonro/Get-ChildItemColor)を導入すると色付きlsのように表示できます。

```powershell
Install-Module Get-ChildItemColor -Scope CurrentUser -AllowClobber
```

更に`Get-ChildItemColorFormatWide`コマンドで`Get-ChildItem | Format-Wide`を色付きで表示できます。

# 設定を保存する

Windows PowerShell / PowerShell Core起動時に実行したい内容を以下のように設定します。

`$profile` はプロファイルのパスが設定されているので次のコマンドで開けます。
ですがWindows PowerShellとPowerShell Coreでパスが違うので両方使う場合はそれぞれのパスのファイルに設定が必要です。

```powershell
# プロファイルを空ファイルで作成する
New-Item -Path $profile -Type file -Force

# メモ帳でプロファイルを開く
notepad $profile

# デフォルト(Restricted)ではスクリプトの実行が許可されていないので
# セキュリティポリシーを変更する
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
```

```powershell:Microsoft.PowerShell_profile.ps1
Set-PSReadlineOption -EditMode Emacs
Import-Module posh-git
Import-Module Get-ChildItemColor
```

# 参考リンク

- [PowerShellGetをアップデートしよう](https://blog.shibata.tech/entry/2017/12/18/004105)
- [PowerShellGet 2.2.3](https://www.powershellgallery.com/packages/PowerShellGet/2.2.3)
- [dahlbyk/posh-git](https://github.com/dahlbyk/posh-git)
- [PowerShell Core のキーバインドをカスタマイズする【PSReadLine】](https://dev.classmethod.jp/etc/powershell-core-6-psreadline/)
- [PSReadLine](https://docs.microsoft.com/ja-jp/PowerShell/module/psreadline/)
scratchイメージを使用する際にx509: certificate signed by unknown authorityが出る

# はじめに
goでdocker imageを作る際はgoイメージ上で実行ファイルをビルドし，実行ファイルをscratchなイメージにコピーしてdocker imageを生成しております．
いざ生成したdocker imageを実行する際にタイトルのエラーが出る場合あります．
毎回対処法を忘れてしまうので備忘録として残します

# 最終的なdockerfile
```
FROM golang:1.12-alpine as builder

RUN apk update && apk add git make

WORKDIR /app

ENV GO111MODULE=on

COPY go.mod .
COPY go.sum .
RUN go mod download

COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o goapp cmd/root/main.go

# for reduce image size
FROM scratch
COPY --from=builder /app/goapp /app/
####### これが必要 ##############
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

ENTRYPOINT ["/app/goapp"]
```
Go のバイナリに静的ファイルを埋め込む assets-life を使ってみた  

## BackGround
Go はシングルバイナリであることによる、配布のしやすさが利点である言語です。
しかし、時々 Go のソースコードへは含めることのできないファイル (テンプレートファイルなど) を、 
外部に持たせられなければならない場合がります。

そこで、Go では Package (外部ライブラリ) により、 
build した実行隊に静的ファイルを埋め込む機能がいくつか提案されてきました。 

今回はその中でも、最近リリースされた [assets-life](https://github.com/shogo82148/assets-life) という package を使ってみたので紹介します。  

## Target
* 制約なし

## Goal
* `assets-life` を使って Go のバイナリに静的ファイルを埋め込めるようになる

## Environment
* `Go`
 * `1.12`
* `assets-life`
 * `9f8d070f229f24f8dd21ba18b19e3aedfa895d3e`

## assets-life
今回紹介する `assets-life` の他には、 
以下のツールが同じ機能を持つものとしてリリースされています。  

* [jessevdk/go-assets](https://github.com/jessevdk/go-assets)
* [jessevdk/go-bindata](https://github.com/jteeuwen/go-bindata)
* [rakyll/statik](https://github.com/rakyll/statik)

これらのうち、`go-assets` と `go-bindata` は、 
以下の理由から、今開発に採用するのは難しい状態となっています。  

* 長期間メンテナンスされていない

なお、`statik` は、 `Awesome Go` に掲載されており、現在のスタンダードとなっているようです。

今回紹介する、`assets-life` は、2019/7 にリリースされたツールです。 
作者の意図として、これまでの競合ツールより使いやすく、パフォーマンスを向上させる意図があるようです。 

この package には以下の特徴があります。  

* コードの再生成にコマンドの再インストールが不要
* ファイルの検索にバイナリサーチを使用しており、概ねのユースケースで高速 (※)

※ 静的ファイルの数が1000以下の場合

なお、本記事執筆時点のリポジトリを見た所では、以下の点には気をつけた方が良さそうです。 
これからの開発に期待です。  

* エラーハンドリングを一部省略している
    * `filepath.Walk()` の `WalkFunc` のエラー処理をしていない
* Windows で `go generate` によるコード再生成ができない


## Example
使い方を簡単な例を元に説明します。  
コマンドのインストールまでの手順については、github の Usage を参照してください。

まず、以下のような静的ファイルのソースを用意します。  

```
.
├── assets_src
     └── hoge.txt
```

```hoge.txt
hoge
```

次に、`assets-life` コマンドでソースから Go ソースコードを生成します。  

```
$ assets-life ./assets_src ./assets
($ cmd src dst)
```

すると、以下のようにファイルが生成されます。

```
.
├── assets
│   ├── assets-life.go
│   └── filesystem.go
├── assets_src
     └── hoge.txt
```

生成された `filesystem.go` には、読み込んだファイルが以下のように実装されています。 
このファイルを `assets` package として import することができます。  
変数 `Root` は `http.FileSystem` インターフェースを実装しており、
 `Open()` メソッドを利用して、各ファイルにアクセスすることができます。  

```filesystem.go
package assets

(中略)

// Root is the root of the file system.
var Root http.FileSystem = fileSystem{
	file{
		name:    "/",
		content: "",
		mode:    0755 | os.ModeDir,
		next:    0,
		child:   1,
	},
	file{
		name:    "/hoge.txt",
		content: "hoge\r\n",
		mode:    0644,
		next:    -1,
		child:   -1,
	},
}

(以下略)
```

このパッケージを元に、以下のようなユーザプログラムを書くと、
静的ファイルにアクセスすることができます。

```main.go
package main

import (
	"fmt"
	"io/ioutil"
	"log"

	"github.com/akif999/prototypes/go/assets_life_exp/assets"
)

func main() {
	f, err := assets.Root.Open("/hoge.txt")
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()

	b, _ := ioutil.ReadAll(f)
	fmt.Println(string(b))
}
```

```
$ XXX.exe
hoge
```

とても簡単に静的ファイルをバイナリに含めることができました。

また、特徴にある通り、静的ファイルを変更した場合、初回生成に使用したコマンドは不要です。 
以下のように Go 標準ツールの `go generate` によって、再生成することができます。 (※)

```
$ go generate ./assets
```

※ Windows 環境では、生成される `go:generate` への引数となるパスセパレータに問題があり、動作しませんでした

## RoundUp
以下、今回の記事のまとめです。

* Usage がわかりやすく誰でも簡単に使える
* まだ開発中な package である
* 現状は `statik` を使用した方が安定していると考えられる

## Reference
* [github.com/shogo82148/assets-life](https://github.com/shogo82148/assets-life)
* [Goのバイナリに静的ファイルを埋め込むツール assets-life を書いた](https://shogo82148.github.io/blog/2019/07/24/assets-life/)
埴安神袿姫の方形造形術を再現してみた

# はじめに
この記事は，東方鬼形獣6面ボス埴安神袿姫の方形造形術を再現するための解説をするものである．

なお，解説には三角比を用いるため，閲覧にあたってはそれに関する知識を持っていることが望ましい．ただし，本記事の最後に弾幕を再現するスクリプトの例も示してあるので「よくわからないけど遊んでみる」ということも可能である．

# 再現する弾幕
今回再現するのは，下記画像のように「全方位に向かって方形に弾を撃つ弾幕」である．以下ではこの弾幕を「方形弾幕」と呼ぶ．

![方形弾幕の画像](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478774/498022c6-a6a0-e33f-4603-d4b615e2f929.png)

# 解説
ある1点から全方位に向かって同じ速さで弾を発射すると，単位時間あたりに進む弾の距離はすべて等しいから，弾幕は円形になる．これを方形にするためには，発射角に応じて弾の速さを変える必要がある．なぜなら，円はどの角度でも中心からの距離が等しい図形であるが，方形は違うからである[^1]．
[^1]: 方形の「中心」としては対角線の交点を考えればよい．

![円と方形の違い](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478774/ae10060b-fe69-885b-2976-ce2b64069b96.png)

従って，やることは角度に応じた速さを求めることであるが，速さは「単位時間あたりに進む距離」のことだから，結局上図でいうところの橙色の線の長さを考えればよい．

![figure2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478774/55efd3b2-996b-6814-cd84-48384d6f5570.png)

直角三角形OABに注目すると，三角比の定義から

```math
\cos\theta=\frac{\mathrm{OB}}{\mathrm{OA}}
\Leftrightarrow
\mathrm{OA}=\frac{\mathrm{OB}}{\cos\theta}
```
であることがわかる．このことを利用して弾の速さを設定してやればよい．

# スクリプト
上記での議論をベースにして実際に東方弾幕風v0.12mで方形弾幕を再現する関数を作成した一例を示しておく．

```
// x: 発射場所のx座標
// y: 発射場所のy座標
// speed: 最も遅い弾の発射速度
// angle: 方形のある1辺の中点に来る弾の発射角
// grf: 弾画像
// delay: 遅延時間
// way: 45°あたりの弾の数
function Square(x,y,speed,angle,grf,delay,way) {
	let gap = 45/way;
	loop(4) {
		ascent(i in 0..way) {
			CreateShot01(x,y,speed*1/cos(gap*i),angle+gap*i,grf,delay);
		}
		
		angle += 45;
			
		ascent(i in 0..way) {
			CreateShot01(x,y,speed*1/cos(45-gap*i),angle+gap*i,grf,delay);
		}
			
		angle += 45;
	}
}
```
次の図は上記のスクリプトでやっていることのイメージ図である．下図では矢印の向きが反時計回りになっているが，東方弾幕風では「角度の正の向き＝時計回り」になっていることは留意しておいたほうがよい．

![実装イメージ図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478774/ccf4533a-118b-bfcb-b29a-956fb109d8d4.png)

# その他
- 鬼形獣は良い曲ばっかり．
AppGoatで学ぶファジング

# ファジングとは？
特定のシステムにファズ（予測不可能な入力データ）データを与えることで意図的に例外を発生させ、その例外の挙動を確認する方法をファジングと呼びます。
歴史は非常に古く、元祖となるツールは1989年に開発されたUNIXアプリケーションの脆弱性テストツールと呼ばれています。
https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%B8%E3%83%B3%E3%82%B0

2019年2月にGoogleが「ClusterFuzz」というファジングツールをOSS化した事が記憶に新しいですが、
ファジングはシステムの脆弱性診断を行う上で必ず理解しなければいけない概念です。
https://github.com/google/clusterfuzz
※AppGoatではIPAが提供する「ファイルフォーマットファザー」というファジングツールを使います。実用性があるかと言われると微妙なので、平行して別ツールを探さないと技術は身に着かないかも・・・

# ファイルフォーマットファザーを使った脆弱性診断体験

ファイルフォーマットファザーは、検証用のファイルを生成し検証対象を診断するツールです。
生成する検証用ファイルの仕様は以下
![ファジングの検証.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36448/bc006726-974a-5e6a-a748-f13e3a7cf5a6.png)

ファイル名の長さと圧縮データのサイズとExtra Fieldの長さで検証してくれる仕様の様で、一つ前の記事で書いた通り、バッファオーバーフロー対策が不要な言語であればそもそも不要なツールですね。
ただ、学習の過程でZipの仕様をまとめた資料が見つかったので学びはあったかなという所。
https://gist.github.com/ysakasin/2edf8d3bf55c6ebf63f82851e302b030

個人的なニーズが高まったら、ClusterFuzzを使ってみた系の記事を書こうかなという所・・・
とりあえず次回はFTPプロキシソフトの異常終了についてまとめます。
WindowsでDatadog Agent Managerが起動しない時の対処

## 環境
Windows10

## 困ったこと
https://app.datadoghq.com/signup/agent#windows
の「Standard installation」でmsiからインストール後、Datadog Agent Managerが起動せず..

## 解決法
スタートメニューにあったDatadog Agent Managerのアイコンを「管理者として実行」したら普通にブラウザで開きました...
または
http://127.0.0.1:5002/
にアクセスしても開けました

## 余談
datadogを一度アンインストールしようとしたところWindowsの「設定 ＞ アプリと機能」からはアンインストールできず、再度datadogのインストーラー起動したら「Remove」からアンインストールできました。
LINQってNumpyに似てる！

# はじめに
最近、C#を勉強し始め、LINQに出会ったのですが、「これPythonのNumpyに似てる！」と思ったので、自分の頭の整理も兼ねて実装を比較してみます。

# 参考にさせて頂いたページ
* [はじめての LINQ](https://qiita.com/nskydiving/items/c9c47c1e48ea365f8995)
* [LINQチートシート的なもの](https://qiita.com/Marimoiro/items/0e119b47d65bf138789a)

# 実装の比較
処理内容毎にLINQの実装、Numpyの実装の順に書いています。

## 配列の作成
```Sample.cs
var arr = Enumerable.Range(0, 6);
Console.WriteLine(string.Join(" ", arr));
// 0 1 2 3 4 5
```
```Sample.py
arr = np.arange(6)
print(arr)
# [0 1 2 3 4 5]
```

## Sum
```Sample.cs
Console.WriteLine(arr.Sum());
// 15
```
```Sample.py
print(arr.sum())
# 15
```

## Max
```Sample.cs
Console.WriteLine(arr.Max());
// 5
```
```Sample.py
print(arr.max())
# 5
```

## Sort（降順）
```Sample.cs
var arr2 = arr.Reverse();
Console.WriteLine(string.Join(" ", arr2));
// 5 4 3 2 1 0
```
```Sample.py
arr.sort()
print(arr[::-1])
# [5 4 3 2 1 0]
```

## 末尾の要素を取得
```Sample.cs
Console.WriteLine(arr.Last());
// 5
```
```Sample.py
print(arr[-1])
# 5
```

## 部分配列を取得
```Sample.cs
var arr3 = arr.Skip(1).Take(3);
Console.WriteLine(string.Join(" ", arr3));
// 1 2 3
```
```Sample.py
print(arr[1:-2])
# [1 2 3]
```

## 条件指定で部分配列を取得
```Sample.cs
var arr4 = arr.Where(x => x % 2 == 0);
Console.WriteLine(string.Join(" ", arr4));
// 0 2 4
```
```Sample.py
print(arr[arr % 2 == 0])
# [0 2 4]
```

## 加工
```Sample.cs
var arr5 = arr.Select(x => x * x);
Console.WriteLine(string.Join(" ", arr5));
// 0 1 4 9 16 25
```
```Sample.py
print(arr * arr)
# [ 0  1  4  9 16 25]
```

## 複数のシーケンスをまとめてループ
```Sample.cs
var arr6 = arr;
var arr7 = arr.Zip(arr6, (a1, a6) => a1 + a6);
Console.WriteLine(string.Join(" ", arr7));
// 0 2 4 6 8 10
```
```Sample.py
arr2 = arr
arr3 = np.array([], dtype=np.int32)
for a1, a2 in zip(arr, arr2):
    arr3 = np.append(arr3, a1 + a2)
print(arr3)
// [ 0  2  4  6  8 10]
```
Rubyでsuperなメソッドが定義されているかを調べる

タイトルまんまなんで早速本題

# 本題

```ruby
class Foo
  def hoge
    super if defined?(super) # これより上で`hoge`が定義されているかは不明
    puts :foo
  end
end

class Bar < Foo
  def hoge
    super # Fooで`hoge`が定義されているのは知ってるからここはそのままsuper
    puts :bar
  end
end

Bar.new.hoge # => "bar\nfoo\n"
```

`super if defined?(super)`がキモ。言われてみればそのままだけど、なかなか思いつかなかった。

# 参考資料

ぶっちゃけ、ここで見たことを書き写したようなもんです。

http://www.virtuouscode.com/2010/09/24/checking-the-existence-of-a-super-method-in-ruby/
同じファイルをuploadしたときに@changeが発火しない

### 同じファイルをupload時に`@change`が発火しない
Vue.jsで[この記事](https://qiita.com/HikaMashiro/items/655729bc1893392dfd42)を参考に画像アップロード・プレビュー機能を作っていたら、一度アップした画像を取り消した後再度同じ画像をアップすると`@change`が発火しなかった

### 解決策
refでDOM要素を引っ張ってvalueを消す

```form.vue
<template>
...
  <label class="img-title-label" v-show="!imageUrl"
    >画像を選択
    <input ref="imageUploader" type="file" @change="onFileChange" />
  </label>
...
</template>

<script>
...
  methods: {
    removeImage() {
      this.$refs.imageUploader.value = ''
      this.imageUrl = ''
      this.imageTitle = ''
    }
}
...
</script>
```
> ref は要素または子コンポーネントに参照を登録するために使用されます。参照は親コンポーネントの $refs オブジェクトのもとに登録されます。プレーンな DOM 要素に使用する場合は、参照はその要素になります。

[公式ドキュメント](https://jp.vuejs.org/v2/api/#ref)
参照が残ってるってことでよいのかしら

### thanks
- [Vue.jsでファイルアップロードの実装--ついでにプレビュー機能も実装した話--](https://qiita.com/HikaMashiro/items/655729bc1893392dfd42)
- [VueJS: Input file selection event not firing upon selecting the same file](https://stackoverflow.com/questions/54124977/vuejs-input-file-selection-event-not-firing-upon-selecting-the-same-file)
- [#ref](https://jp.vuejs.org/v2/api/#ref)
【JavaScript】Reactでも使える便利な配列操作まとめ

# Reactでも使える便利な配列操作まとめ
Reactで配列を使用する際に、知っていると便利なJavaScriptの配列操作まとめです。

## 配列をコピー： *slice*
配列名.slice()で、配列をコピーできます。
()に値を指定すれば、コピーする範囲を指定できます。

```react.js
const animalsList = [dog, tiger, lion, wolf, bison, fox, rabbit];

// 全てコピー
const animalsList2 = animalsList.slice();
// 3番目の要素から全てコピー
const animalsList3 = animalsList.slice(2);
// 1番目の要素から5番目の要素までコピー
const animalsList4 = animalsList.slice(0, 4);

console.log(animalsList);
console.log(animalsList2);
console.log(animalsList3);
console.log(animalsList4);
```
```:console.log
[dog, tiger, lion, wolf, bison, fox, rabbit]
[dog, tiger, lion, wolf, bison, fox, rabbit]
[lion, wolf, bison, fox, rabbit]
[dog, tiger, lion, wolf, bison]
```

## 配列の先頭に追加： *unshift*
配列名.unshift(要素)で、配列の先頭に要素を追加できます。
()に値を複数入れれば、複数の要素を追加できます。

```react.js
const animalsList = [dog, tiger, lion, wolf, bison, fox, rabbit];
const animalsList2 = animalsList.slice();
animalsList2.unshift('cat');

console.log(animalsList);
console.log(animalsList2);

animalsList2.unshift('mouse', 'elephant');
console.log(animalsList2);
```
```:console.log
[dog, tiger, lion, wolf, bison, fox, rabbit]
[cat, dog, tiger, lion, wolf, bison, fox, rabbit]
[mouse, elephant, cat, dog, tiger, lion, wolf, bison, fox, rabbit]
```

## 配列の末尾に追加： *push*
配列名.push(要素)で、配列の末尾に要素を追加できます。
()に値を複数入れれば、複数の要素を追加できます。

```react.js
const animalsList = [dog, tiger, lion, wolf, bison, fox, rabbit];
const animalsList2 = animalsList.slice();
animalsList2.push('cat');

console.log(animalsList);
console.log(animalsList2);

animalsList2.push('mouse', 'elephant');
console.log(animalsList2);
```
```:console.log
[dog, tiger, lion, wolf, bison, fox, rabbit]
[dog, tiger, lion, wolf, bison, fox, rabbit, cat]
[dog, tiger, lion, wolf, bison, fox, rabbit, cat, mouse, elephant]
```

## 配列の先頭を削除： *shift*
配列名.shift()で、配列の先頭の要素を削除できます。

```react.js
const animalsList = [dog, tiger, lion, wolf, bison, fox, rabbit];
const animalsList2 = animalsList.slice();
animalsList2.shift();

console.log(animalsList);
console.log(animalsList2);
```
```:console.log
[dog, tiger, lion, wolf, bison, fox, rabbit]
[tiger, lion, wolf, bison, fox, rabbit]
```

## 配列の末尾を削除： *pop*
配列名.pop()で、配列の末尾の要素を削除できます。

```react.js
const animalsList = [dog, tiger, lion, wolf, bison, fox, rabbit];
const animalsList2 = animalsList.slice();
animalsList2.pop();

console.log(animalsList);
console.log(animalsList2);
```
```:console.log
[dog, tiger, lion, wolf, bison, fox, rabbit]
[dog, tiger, lion, wolf, bison, fox]
```

## 要素数を確認： *length*
配列名.lengthで、配列の要素数が確認できます。

```react.js
const animalsList = [dog, tiger, lion, wolf, bison, fox, rabbit];

console.log(animalsList.length);
```
```:console.log
7
```
# まとめ
覚えておくと便利な配列操作一覧

- **要素数を確認： 配列名.length**
- **配列をコピー： 配列名.slice()**
- **配列の先頭に追加： 配列名.unshift(要素)**
- **配列の末尾に追加： 配列名.push(要素)**
- **配列の先頭を削除： 配列名.shift()**
- **配列の末尾を削除： 配列名.pop()**

今回は、以上になります。ご覧いただき、ありがとうございました！
ChromeでMediaSessionAPIを使う

# そもそもMediaSessionとは?
皆さんはWindows10等を使っていますでしょうか？
Grooveミュージックなどで再生するとロック画面や音量変更時に隣に出てくるアイツの様なやつです。
なお、ChromeでYouTubeを使用すると出てきます。
こんなやつです↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349992/5c7020e3-3d00-12c4-e1fb-692af83027d2.png)
今回は、Chromeで実際にMediaSessionAPIを叩いていこうと思います。
対応状況として、現在は実験的な機能であり、PC版Chrome(73)、Android版Chrome(57)以降のみでしか対応していません。
詳しくはここから: https://developer.mozilla.org/ja/docs/Web/API/MediaSession
# コード
```html:index.html
<!DOCTYPE html>
<html>
    <head>
        <title>MediaSession TEST</title>
        <meta charset="UTF-8">
        <script src="test.js" charset="UTF-8"></script>
    </head>
    <body>
        <audio id="player" src="" controls></audio>
        <button id="play" onclick="test()" >再生</button>
    </body>
</html>
```
```javascript:test.js
function test(){
    var audio = document.querySelector("#player"); 
    audio.src = "test.mp3"; //任意の音源データ選択
    if ('mediaSession' in navigator){
        navigator.mediaSession.metadata = new MediaMetadata({
            title: "てすと", //音声のタイトル
            artist: "MediaSession", //　アーティスト
            album: "てすと", //アルバム名 (Chrome79から別機能でアルバム名も表示されるようになったので忘れないように!)
            artwork: [{ src: "https://dummyimage.com/600x600/1ea845/000000.png",  sizes: '540x540',   type: 'image/jpeg' }] //アートワーク(推奨500px以上、サイズやタイプ指定が無ければ表示されない?)
        });
        navigator.mediaSession.setActionHandler('play', function() {audio.play();}); //再生ボタン押下時の動作
        navigator.mediaSession.setActionHandler('pause', function() {audio.pause();}); //一時停止ボタン押下時の動作
        //navigator.mediaSession.setActionHandler('seekbackward', function() {}); //後ろにシークした時の動作(?)
        //navigator.mediaSession.setActionHandler('seekforward', function() {}); //前にシークした時の動作(?)
        navigator.mediaSession.setActionHandler('previoustrack', function() {}); //前ボタン押下時の動作(今回は未使用)
        navigator.mediaSession.setActionHandler('nexttrack', function() {}); //次ボタン押下時の動作(今回は未使用)
    }
    audio.play(); //再生
}
```
出来ました!!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349992/0ac7ccb8-5f68-c803-828d-96e165b9eac2.png)

# 注意点
アートワークのソースはhttp,https,data,blobのみ使えます。
MDNの例( https://developer.mozilla.org/ja/docs/Web/API/MediaSession )ではアートワークの部分が以下の様に
なっていますが、ソースの他に、サイズやファイルタイプ等を入力しなければいけない事が分かりました。
修正前

```javascript
artwork: [{src: "podcast.jpg"}]
```
修正後

```javascript
artwork: [{ src: "https://dummyimage.com/600x600/1ea845/000000.png",  sizes: '540x540',   type: 'image/jpeg' }]
```
# 参考にした所
https://developer.mozilla.org/ja/docs/Web/API/MediaSession

# 変更
2019/09/08 タイトルに誤字があったので修正しました。
2020/01/09 サンプルコード(JS側)のアルバム部分にコメント追加。
Chrome79(?)からのメディアコントロール画面(?)ではアルバム名もそのまま表示されるので長すぎても良くないと思います。
aws ec2の時刻がずれた時の対処法

アプリケーションサーバーのログの時間と、DBに登録される時間が大幅にずれていて、不具合に悩まされたのでメモです。

ec2サーバーがntpサーバーの同期が取れていなくて、サーバーの時刻がたまにずれていることがある。

ntpqコマンドを使ってntpサーバーの同期の確認、それからntpサーバーの同期を取ったあとntpdを再起動することで対処可能

・時刻がずれてた時の確認内容

サーバーの現在時刻確認
ここが他のサーバーと大きくずれている場合、ntpサーバーと同期が取れてない可能性がある。

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ date
2019年  9月  8日 日曜日 07:27:09 UTC
```

ntpサーバーの同期調査
*がどこかのサーバーに付いていれば、同期されているので、時刻がずれることはないはず。

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*169.254.169.123 10.206.239.196   3 u    4    8  377    0.236   -0.877   0.133
 2.amazon.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.000
+kuroa.me        242.71.143.169   2 u   27   64   37    9.782   -1.240  95.515
-149.28.28.160 ( 103.1.106.69     2 u   27   64   37    4.320   -0.580  95.256
+sv1.localdomain 133.243.238.244  2 u   28   64   37    3.486   -1.475  94.768
-ec2-13-230-38-1 133.243.238.243  2 u   20   64   27    1.884   -1.152  86.029
```

・もしntpサーバーと同期が取れていない場合、どうするか。
ntpdateでntpサーバーと同期した後にntpdを再起動する。

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo service ntpd stop
Shutting down ntpd:                                        [  OK  ]
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo ntpdate -Bv 0.amazon.pool.ntp.org
 8 Sep 09:33:59 ntpdate[23382]: ntpdate 4.2.8p12@1.3728-o Fri May  3 15:36:35 UTC 2019 (1)
 8 Sep 09:34:05 ntpdate[23382]: adjust time server 18.182.27.134 offset -0.000604 sec
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo service ntpd start
Starting ntpd:                                             [  OK  ]
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo service ntpd status
ntpd (pid  23401) is running...
```

時刻の確認

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ date
2019年  9月  8日 日曜日 09:34:07 UTC
```

ntpdの状況確認

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ ntpstat
synchronised to NTP server (169.254.169.123) at stratum 4
   time correct to within 17 ms
   polling server every 256 s
```

ntpサーバー同期の確認

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*169.254.169.123 10.206.239.196   3 u    6   16  377    0.198   -0.028   0.019
 2.amazon.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.000
+ntp-b2.nict.go. .NICT.           1 u   56   64  377    5.412   -0.525   0.434
-ec2-18-182-27-1 133.243.238.163  2 u   60   64  377    0.364   -0.571   0.384
-y.ns.gin.ntt.ne 249.224.99.213   2 u   58   64  377    3.944    1.781   0.555
+kuroa.me        242.71.143.169   2 u   59   64  377    9.750   -0.203   0.394
[ec2-user@ip-172-31-28-129 ~]$
```

※古いAMIを使ってるサーバーも多いと思うが、awsで提供されているAmazon Linux2を使えば、Amazon Time Sync Serviceが使えるので、ntpサーバーの同期で悩む心配はないと思う。
https://dev.classmethod.jp/etc/amazon-linux-ami-2018-03-amazon-time-sync-service/

予防できないか考えたが、そもそも時刻がずれる原因が対策できないものもあると思うので、定期的に確認して、時刻がずれてないか確認するのがいいかなーと思います。

一番いいのはAmazon Linux2を使うことだと思いますけど。
PowerShellでBEEP音を鳴らす

#前書き
PowerShellでBEEP音を鳴らすことができれば、自動処理中の結果を音で知らせることができます。
今回はその方法を調べました。

こんな感じになります。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">古のテクニックBEEP音 <a href="https://t.co/oQM3vMHQga">pic.twitter.com/oQM3vMHQga</a></p>&mdash; m.ita (@mima_ita) <a href="https://twitter.com/mima_ita/status/1170630307101298688?ref_src=twsrc%5Etfw">September 8, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


# Beep音の鳴らし方
WinAPIの[Beep](https://docs.microsoft.com/en-us/windows/win32/api/utilapiset/nf-utilapiset-beep)をC#経由で呼び出します。

```powershell
$source = @"
using System;
using System.Runtime.InteropServices;

public static class WinApi
{
    [DllImport("kernel32.dll")]
    public static extern bool Beep(int freq,int duration);
}
"@
Add-Type -TypeDefinition $source
```


## 実行例

```powershell
	[WinApi]::Beep(440, 2000)
```

第一引数に周波数、第二引数に継続するミリ秒を入力します。

## 追記
ConsoleオブジェクトがBeepサポートしていました（震え）

```powershell
	[Console]::Beep(440,2000)
```


# 音楽を鳴らしてみる。
古のテクニックでBEEP音で音楽を鳴らすという技があります。
下記のページに周波数と音階の対応表があるので利用します。

**メロディのプログラム**
http://web.archive.org/web/20190116021421/http://www.geocities.jp/shuinoue/myurobo/prog1.html


```powershell
# http://web.archive.org/web/20190116021421/http://www.geocities.jp/shuinoue/myurobo/prog1.html
function global:Snd([string]$key, [int]$duration=100) {
    $KeySignature = @{
        "Fa-1"  = 294;
        "FaS-1" = 311;
        "So-1"  = 330;
        "SoS-1" = 349;
        "La-1"  = 370;
        "LaS-1" = 392;
        "Si-1"  = 415;
        "Do"  = 440;
        "DoS" = 466;
        "Re"  = 494;
        "ReS" = 523;
        "Mi"  = 554;
        "Fa"  = 587;
        "FaS" = 622;
        "So"  = 659;
        "SoS" = 699;
        "La"  = 740;
        "LaS" = 784;
        "Si"  = 831;
        "Do+1"  = 880;
        "DoS+1" = 932;
        "Re+1"  = 988;
        "ReS+1" = 1047;
        "Mi+1"  = 1109;
        "Fa+1"  = 1175;
        "FaS+1" = 1245;
        "So+1"  = 1319;
        "SoS+1" = 1397;
        "La+1"  = 1480;
        "LaS+1" = 1568;
        "Si+1"  = 1661;
        "Do+2"  = 1760;
        "DoS+2" = 1865;
        "Re+2"  = 1976;
        "ReS+2" = 2093;
        "Mi+2"  = 2218;
        "Fa+2"  = 2349;
        "FaS+2" = 2489;
        "So+2"  = 2637;
        "SoS+2" = 2794;
        "La+2"  = 2960;
        "LaS+2" = 3136;
        "Si+2"  = 3322;
    }
    #
    $freq = $KeySignature[$key]
    $ret = [WinApi]::Beep($freq, $duration)
}
```

以下のように鳴らします。

```powershell

Snd So-1 300;Snd Do 300;Snd Mi 300;Snd So 300;Snd Do+1 300;Snd Mi+1 300;Snd So+1 600;Snd Mi+1 600;
Snd SoS-1 300;Snd Do 300;Snd ReS 300;Snd SoS 300;Snd Do+1 300;Snd ReS+1 300;Snd SoS+1 600;Snd ReS+1 600;
Snd LaS-1 300;Snd Re 300;Snd Fa 300;Snd LaS 300;Snd Re+1 300;Snd Fa+1 300;Snd LaS+1 900;
Snd Si+1 300;Snd Si+1 300;Snd Si+1 300;Snd Do+2 1200;
```

# まとめ
今回はBEEP音をならしてみました。
簡単な警告音ならともかく、令和の時代なので音楽は別の方法で鳴らした方がいいと思った（こなみかん）。
CのIntel CompilerでOpenMP対応のソースコードをコンパイルしたときのメモ

# 概要

```
$ icc -openmp main.c
```

のようにコンパイルすると

```
dyld: Library not loaded: libiomp5.dylib
Reason: image not found
```

のようなエラーが返ってきました。

# 解決方法

次のようにコンパイルオプションを付与すると解決。

```
$ icc -openmp -static-intel main.c
```

これでIntel Compilerで問題なくOpenMPが使えました。
nginx で オレオレ証明書をする

# 概要
http だと、chromeなどで「保護されていない通信」と表示されてしまう。
ちゃんとしたサイトっぽいので、https へと変換しよう！
[こちら](https://kitsune-programming.com/nginx-ssl)を参考に設定させて頂きました！

# やることリスト
- openssl インストール
- 秘密鍵の作成
- CSR（証明書署名要求）の作成
- CRT（SSLサーバ証明書）の作成
- nginx の設定

# ファイルの作成
### openssl のインストール

```
$ sudo yum install openssl
```

### 秘密鍵の作成

```
$ sudo mkdir /etc/nginx/ssl
$ sudo openssl genrsa -out /etc/nginx/ssl/server.key 2048
```

### CSR（証明書署名要求）の作成
```
$ sudo openssl req -new -key /etc/nginx/ssl/server.key -out /etc/nginx/ssl/server.csr
```
「Common Name」には、サーバのドメイン名を入力します。
↓参考画像 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387311/b86034f9-3ca5-ef3d-b5e9-014fc335bab5.png)

作成されたファイルを確認すると、2つのファイルが出来ています。

```
$ ls /etc/nginx/ssl
server.csr  server.key
```

### CRT（SSLサーバ証明書）の作成
今回はオレオレ証明書を作成するので、CRTファイルは自分で作成します。
本来このファイルは、証明局へ登録すると発行してもらえるファイルになります。

```
$ sudo openssl x509 -days 3650 -req -signkey /etc/nginx/ssl/server.key -in /etc/nginx/ssl/server.csr -out /etc/nginx/ssl/server.crt
$ ls /etc/nginx/ssl/
server.crt  server.csr  server.key
```

これで、3ファイルの作成が完了です。

# nginxの設定

```
$ sudo vi /etc/nginx/conf.d/[任意のファイル].conf
server {
    # 443番ポートを許可し、SSL機能をON
    # listen 80;
    listen 443 ssl;

    # 証明書を設定
    ssl_certificate     /etc/nginx/ssl/server.crt;
    ssl_certificate_key /etc/nginx/ssl/server.key;
}
```

nginx を再起動

```
$ sudo systemctl restart nginx
```

[https://サーバのURLかドメイン] で接続して、確認
オレオレ証明書なので、ブラウザでブロックされるので、そのまま進めば自分のページが見れます。
ログよりデータの中身を見る。

うまくいってなくて困ったときは、どこまでどういうデータがとんでるのか、知ることが大事。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390823/019eb325-a39d-7276-6bce-5f9d088b3d17.png)

＄thisでデータの中身を見る。
作成したファイル名￥app￥tmp￥logs￥error.logにて確認できる。
[AWS]EC2インスタンスを作成し、SSH接続できるまでにつまづいたこと[ドラフト]

AWS初心者の私が、EC2インスタンスを作成し、SSH接続できるまでにつまづいたことです。

さらにいうと、秀和システムの「Amazon Web Service アプリ開発運用」という本の第３章をやっている際に、つまづいたところです。


# VPCのサブネット、Internet Gatewayを自分で作る必要があった
本では、VPC作成時にサブネットおよびInternet Gateway は自動で作られているようでしたが、2019/09/08現在、それらは自分で作る必要があるようでした。

- サブネットに関しては、EC2インスタンス作成時ににVPCを設定する際に、怒られます。

`// TODO
 VPC Dashboard -> Subnets といって作成しましょう。`

- Internet Gatewayに関しては、Elastic IPをインスタンスに割り当てるときに、「Network vpc-0408fe634bf38c9a9 is not attached to any internet gateway」と怒られます。

`// TODO
 VPC Dashboard -> Internet Gateways といって作成しましょう。`

<img width="1002" alt="Screen Shot 2019-09-08 at 18.00.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36475/3570d460-20ce-3b05-4abd-7fa7bfda5a2c.png">

 


# Route Table に作成したInternet Gatewayを設定する必要がある
EC2にSSH接続する際に、これをしないと繋がりませんでした。

`//TODO
 VPC Dashboard -> Route Tables と進み、EC2インスタンス（に紐づいているVPC）に紐づいているRoute Tableを選択し、
 [Edit route]でrouteを追加しましょう。
 "Target"に"Internet Gateway"を選択すると、手持ちのGatewayが選択できます。`



<img width="590" alt="Screen Shot 2019-09-08 at 18.16.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36475/8ccc6451-9cb5-6fbe-4648-b5255df3b680.png">

<img width="1327" alt="Screen Shot 2019-09-08 at 18.12.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36475/60f1d12e-93e6-22c6-155f-43afbb12d90d.png">

Destinationはなどは0.0.0.0/0で良いのか正直わかりませんが、とりあえず私の設定ではこれで繋がりました。
適宜設定してください。


以上です！
【ubuntu 18.04 LTS】個人的に便利だと思うショートカットキー

#Ctrl + D
ターミナルを閉じるときに使う。Python の対話モードを閉じる時や、ssh 接続でリモートからログアウトする時にも使える。

#Ctrl + Alt + T
ターミナルを起動するときに使う。

#Alt + Tab
アクティブにするアプリケーションを切り替えるときに使う。
![アプリ切り替え.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192626/3cacda3e-f39f-6f68-0e59-8a29f8054e21.png)

#Ctrl + Alt + 方向キー
ワークスペースを切り替えるときに使う。
![ワークスペース切り替え.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192626/c1a693be-f742-048e-7662-15e771e4a264.png)
[node.js] テキストファイルを読みこみ

**テキストファイルを読むためには readFileSync 関数を使用します。[^1][^2]**

[^1]: ファイルを読むための関数として、readFileSync 関数のほかに、readFile 関数があります。これはファイルを「非同期」的に読むための関数です。「同期」と「非同期」との違いは処理の完了を待つかどうかにあります。「同期」の場合は処理（ここではファイルの読み込み）が完了してから次の処理を実行しますが、「非同期」の場合は処理が完了しなくても次の処理を始めます。場合によっては処理をする前に次の処理を始める場合もあります。ファイルを読み込む場合、ほとんどがそのファイルの全行の読み込みを待ってから次の処理をはじめたいというケースが多いので、ここでは同期処理を行う readFileSync 関数のみを紹介しています。
[^2]: 「同期」と「非同期」のどちらを使うかのメリット・デメリットは処理の内容次第です。ファイルの読み込みでは、「同期」の場合はファイルを読み込むまで処理はプログラムは状態となります。それに対して「非同期」の場合はとりあえず処理は先に進めてくれます。メリット・デメリットを説明する記事はいずれ書きたいと思います。

#概要
1. fs (filesystem) モジュールを使用します。
1. readFileSync 関数でファイル（テキストストリーム）を読み込みます。
1. テキストストリームを split 関数で改行ごとに行を分割します。
1. 各行について処理を実行します。


#例
read_file.js　ファイルを読み出し、コンソールに表示する node スクリプト
sample.txt　read_file.js により読み込まれるファイル
この２つのファイルは同じディレクトリに置く想定です。

```read_file.js
const fs = require('fs');

var text = fs.readFileSync("./test1.txt", 'utf8');
var lines = text.toString().split('¥n');
for (var line of lines) {
  console.log(line)
}
```

```test1.txt
/*
read_file.js により読み込まれるファイルです。
文字コードは UTF-8 、改行コードは CRLF で作成しています。
改行コードを CRLF としているのは筆者の開発環境が Windows のためです。
*/
１行目
２行目
３行目
```

```[実行結果]&nbsp;node&nbsp;read_file.js
１行目
２行目
３行目
```

#説明
##1. fs (filesystem) モジュールを使用します。

```const fs = require('fs');```

「ファイルを読み込む」とは「ファイルシステムを操作する」ということです。
「ファイルシステムを操作」するためには filesystem モジュールを使用する必要があります。
filesystem モジュールを使うためには require 関数で呼び出します。
ここでは、require で filesystem モジュール（fs）を呼び出した後に、ファイルシステムの操作（ここではファイルの読み込み）をするために、fs という定数で定義をしています。今後、fs を使うことによって、filesystem モジュールの関数を使うことができるようになります。


###2. readFileSync 関数でファイル（テキストストリーム）を読み込みます。

```var text = readFileSync('./sample.txt",'utf8');```

ファイルを読み込むために、readFileSync 関数を使用します。

https://nodejs.org/api/fs.html#fs_fs_readfilesync_path_options

```
[String] readFileSync(filepath, encode);
引　数：ファイル名（ファイルパスを含む）、ファイルの文字コードを指定
戻り値：String 型
```

readFileSync 関数の引数にはファイルパス、および、ファイルの文字コードを指定します。

ファイルパスは相対パス、絶対パスどちらでも指定可能です。この例では read_file.js と同じディレクトリに sample.txt がありますので、'./sample.txt' と指定しています。

ファイルの文字コードの指定は、指定していない場合はデフォルトで utf8 と解釈されます。

readFileSync 関数で読み込まれたファイルはテキストストリームとして String 型で戻されます。ここでは text 変数にテキストストリームを格納しています。

テキストストリームとは改行文字を含めたテキストの全データです。テキスト処理は行単位で行いますが、テキストストリームだと行には分かれておらず、改行文字も含めた１つのデータとなっています。そのため、テキストストリームのままでは処理がしにくいです。
次で、改行コードにもとづいて、テキストストリームを分割して、行単位にします。


##3. テキストストリームを split 関数で改行ごとに行を分割します。

```var lines = text.toString().split('¥n');```

ここでは改行コード（\n）でテキストストリームを分割して（split 関数)、lines 変数に格納しています。split 関数は 文字列操作関数で、String 型のデータに対して、引数で指定した文字にもとづいて、分割し、配列として返すという関数です。lines 変数は改行を除く各行を値として収める配列変数になります。

##4. 各行について処理を実行します。

```for (var line of lines) {console.log(line)}```

これは配列変数の操作でよく見る例文ですよね。
ここでは、配列変数 lines に格納されている各要素の値（ここではファイルの各行の文字データ）を、変数 line に格納して、配列の要素の最後まで（ファイルの最後の行まで）、繰り返し、コンソールに表示させています。
実際のテキスト処理はこの
```console.log(line);```
に書き、text 変数に対して処理をします。
VSCode で Python コンテナ内で実行したコードをデバッグする

# 目次
* 環境
* Docker でデバッグ用の Python コンテナ作成
* サンプルコード
* デバッグ

## 環境
macOS Mojave
Docker version 19.03.2, build 6a30dfc

## コンテナ作成
デバッグ（開発）用に使う Python のコンテナイメージを作成する
### Dockerfile
```Dockerfile:Dockerfile
FROM python:3
WORKDIR /app
RUN pip install -U pip \
    && pip install ptvsd
```

### イメージ作成
```
docker build -t python-debug .
```

### コンテナ起動
```
docker run -it -d --name=python-debug -v /path/to/app:/app -p 5678:5678 python-debug
```

## デバッグ
VSCode のデバッグ設定を行う
`⌘⇧P` で　launch.json を開き以下を入力

```json:launch.json
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Attach",
            "type": "python",
            "request": "attach",
            "port": 5678,
            "host": "localhost",            
            "pathMappings": [
                {
                    "localRoot": "${workspaceFolder}", 
                    "remoteRoot": "/app"
                }
            ],
        }
    ]
}
```


### サンプルコード
```python:hello.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys

def main():
    msg = "hello world"
    print(msg)

if __name__ == '__main__':
    if (len(sys.argv) > 1) and (sys.argv[1] == "debug"):
        import ptvsd
        print("waiting...")
        ptvsd.enable_attach(address=('0.0.0.0', 5678))
        ptvsd.wait_for_attach()
    main()
```

ここまできたら、デバッグの準備は終了

```
docker exec -it -d python-debug /bin/bash
```
でコンテナ内に入り、 `python hello.py debug` を実行し、 `waiting...` と表示されたら、
VSCode で適当にブレークポイントを張り、実行するとキャッチできるはず

参考：
[Python Remote Debug](https://qiita.com/kenmasu/items/c46804a30f83bbfc18c8)
[VSCodeでPythonのリモートデバッグ](https://qiita.com/sinsi404/items/dd0afe1ed038d542d1f1)
 ---
#### 余談
個人的には、Python の開発は VSCode よりも  PyCharm の方がやりやすいから、コーディングは PyCharm でして、デバッグは VSCode で行うスタイルがやりやすいです。

VS Code Remote Development で立ち上げたコンテナに接続してもデバッグできないよね...??
それでできる方法あれば参考リンクなど教えてください m(_ _)m
AWSインスタンスでjupyter notebookの起動

# jupyter notebookをAWSインスタンス場で起動
AWSインスタンス上でjupyter notebookを起動するとポート、セキュリティグループの設定が必要になります。
今回の記事では私が詰まったポイントをまとめます。
## インスタンスの作成時
セキュリティグループ: カスタム TCP ルール TCP 8888 マイIP
こちらを通常のグループ(Deep Learning AMI -Ubuntu--24-1-AutogenByAWSMP)に追加で加えてください。この設定でローカルからのブラウザでのアクセスが可能になります。

## SSH接続
```bash
ssh -i path/to/pem ubuntu@yourcomputer.amazonaws.com
jupyter notebook --generate-config
vi /home/ubuntu/.jupyter/jupyter_notebook_config.py
```
jupyter notebookの設定ファイルを作成し、編集を行います。
/home/ubuntu/.jupyter/jupyter_notebook_config.pyとなっていますが、こちらのパスは各自設定を行ってください。--generate-configした後に、ファイルのパスが表示されています。

vimで設定ファイル内に下記コードを書き込んでください。

```vim
c = get_config()
c.NotebookApp.ip = '0.0.0.0'
c.NotebookApp.open_browser = False
c.NotebookApp.port = 8888
c.NotebookApp.token = ''
```


そしてjupyter notebookを起動

```
jupyter notebook
```
http://your.ip:8888/tree?
jupyter起動時に表示されるアドレスではなくAWSのIP v4 publicなどのIPを使う必要があります。
こちらのアドレスにアクセスできたら成功です。
私はセキュリティグループの設定、Notebookのポート開放で詰まりました。
同じように詰まった方の助けになれば幸いです。

## 参考にさせていただいた記事
https://qiita.com/ground0state/items/6d5c96dd14a5cb256f64
AMIにcondaがプリインストールされているため、こちらの記事を参考にさせていただき仮想環境構築の部分をカットしました。
https://qiita.com/mechamogera/items/b1bb9130273deb9426f5
ポートフォワーディングを使用しましたが、私の知識不足のためうまく接続できませんでした。