OmniAICreator/Qiita-1.07M huggingface dataset:
GoogleDrive上でMarkdownファイルを閲覧・編集するには？

## はじめに
ローカルに保存されたMarkdownファイルを閲覧・編集するときは**VSCode**を使用していたのですが、
Googleドライブ上にあるMarkdownファイルを閲覧・編集する際はどうしたらよいのか？と疑問に思い調査しました。
結論としては、
**G Suite Marketplace** の**「StackEdit」**をインストールすることで閲覧・編集可能です。
今回はこのStackEditのインストール方法を紹介です。

## StackEditとは
StackEditとはブラウザ上で動作するMarkdownエディタです。
Googleドライブ、Dropbox、GitLab、GitHubと同期ができます。

## インストール方法
### Google Driveにアプリを「StackEdit」を追加する
[Google Drive](https://drive.google.com/drive)の画面を開いて、
右上にある「+新規」 > 「その他」 > 「アプリを追加」をクリックする。

### StackEditを検索する
G Suite Marketplaceの検索ボックスに「StackEdit」を入力し検索する。
StackEditが表示されるのでインストールする。
インストール途中でGoogle認証の許可を求められるので許可してください。
これでインストールは完了です。
<img width="804" alt="StackEditを検索する" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649584/bba52bf9-0ac3-8309-6764-6469fc4f072c.png">

### インストール時にエラーが発生した場合
私の環境で「このアプリでは「Google でログイン」機能が一時的に無効」と表示されインストールできませんでした。
<img width="641" alt="インストール時にエラーが発生した場合" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649584/87f7e2b0-cca2-2d25-7da9-9550f88bc4e4.png">

解決方法として、
StackEditのWebサイト経由でGoogleドライブにファイルをアップすることによって、
うまく認証することができました。

**1.StackEditのWebサイトへアクセス**
https://stackedit.io/app

**2.Googleサインイン**
右上にあるシャープのアイコンをクリックし、「Sign in with Google」を選択します。
選択するとGoogleのサインインを求められるでサインインしてください。
その後、StackEditがGoogleドライブへアクセスすることの許可を求められるので許可します。
<img width="835" alt="Googleサインイン" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649584/30e9472f-b661-4f10-0ff0-8e44c066e45c.png">

**3.StackEditからPublish**
右上にあるシャープのアイコンをクリックし、「Publish」を選択します。
<img width="352" alt="StackEditからPublish" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649584/d7e9be0d-73bd-7f20-bfe6-5b8f9392c6c5.png">

次にPublishする先として「Googleドライブ」を選択する。
「Add Google Drive account」を選択すると、
Googleドライブへのアクセス許可が出てくるので許可してください。
この許可を行うことでGoogleドライブへの**「StackEdit」のインストールが完了**です。
<img width="281" alt="「StackEdit」のインストール完了" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649584/51148007-f7e5-58a7-15c1-07f425a54755.png">

**4.GoogleドライブでStackEditがインストールされたか確認する**
右上にある「+新規」 > 「その他」 > 「StackEdit」が追加されていればOKです。
<img width="322" alt="StackEditのインストール確認" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649584/797025fd-cbfe-19c3-db63-3315630a9e70.png">

## 終わりに
StackEditは使いやすいしGitHub連携もできるのでGoodです。
【小ネタ】AWSのMFAを設定する前に、IAMユーザのサインインリンクをカスタマイズするとちょっと幸せ

# はじめに
AWSのMFA、設定してますか？

MFAってなーに？
という方は、超丁寧に説明している記事があったので、設定してない人はこれを見て設定してください！
[AWSでMFA(二段階認証)を有効にする方法を超丁寧に説明するよ - Qiita](https://qiita.com/viptakechan/items/6d19aee635b2ab189e47)

最近、MFAを設定していて、タイトルの通りちょっと幸せになったのでまとめます。

# IAMユーザのカスタムリンク
IAMユーザがログインするときのリンク。デフォルトだとAWSアカウント（12桁の数字）。任意の文字列でカスタマイズできる。
アカウントエイリアスとも。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62601/811aecbc-a0f7-ef5d-0383-47f4c4d38dde.png)

**MFAを設定する前に、これをわかりやすい文字列にカスタマイズしましょう。**

# カスタマイズしない場合
piyopiyoさん
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62601/57be15d6-6c8f-fc54-3dc4-f9753845600f.png)

Google Authenticatorでパシャリ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62601/a388e63f-6859-d10a-6755-9005d70947f6.png)

Google Authenticatorでは「ユーザ名＠AWSアカウント（12桁の数字）」になる。
<img width="414" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62601/f9fe8582-e766-a977-40e9-ae3fbfacad2c.png">

# カスタマイズする場合
カスタマイズ：poyopoyo
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62601/35cabf60-ddbc-d27a-ade0-bea47bf38b72.png)

同じくpiyopiyoさん
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62601/57be15d6-6c8f-fc54-3dc4-f9753845600f.png)

Google Authenticatorでパシャリ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62601/a388e63f-6859-d10a-6755-9005d70947f6.png)

Google Authenticatorでは「ユーザ名＠カスタマイズした文字列」になる。
<img width="414" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62601/cd99f9b0-9f02-88b3-6e91-bb2f63a4734b.png">

rootユーザでもIAMユーザでも、同じく反映される。

# おわりに
AWSアカウントが増えると、一体どのアカウントだったか忘れてします。
カスタマイズしておくとちょっと幸せになれます。オススメです。

# おまけ：気づいた経緯
AWSアカウントのMFAを40個くらい登録しているときに、数字とアカウントエイリアスの2パターンがあり、なんだろうと思って調べました。
CSV ファイルの差分（git diff 利用）

こんにちは。
二つの CSV ファイル内の値の差を調べるために、```git diff``` を用いてみました。色付き出力を指定しています。

```console
$ git --no-pager diff --color --word-diff-regex="[^,]+" 1.csv 2.csv
diff --git a/1.csv b/2.csv
index a84bde8..9a2c7e4 100644
--- a/1.csv
+++ b/2.csv
@@ -1 +1 @@
1,2,[-3.4,5-]{+3.5,6+},7
$
$ cat 1.csv 2.csv
1,2,3.4,5,7
1,2,3.5,6,7
$
```

また上記の色付き出力を html ファイル化しました（[aha](https://github.com/theZiz/aha) コマンド利用）。

```console
$ git --no-pager diff --color --word-diff-regex="[^,]+" 1.csv 2.csv | aha --title 1_vs_2 > 1_vs_2.html
```
2020/06/04 プログラミング(フロントエンド)学習5日目 メモ

# 本日の学習範囲
### ドットインストール
・はじめてのCSS #11〜#13
（学習時間：1時間）
## CSS学習メモ
### list-style-typeプロパティ
`{list-style-type: ○○;}`
リスト先頭のマーカー文字の種類を指定する
`{list-style-type: none;}`
でマーカーを削除できる
### align-itemsプロパティ
`{align-items: ○○;}`
コンテナボックス内のアイテムの交差軸方向の揃え位置を指定する
`{align-items: center;}`
で交差軸方向において中央揃えにできる
### 主軸
コンテナボックス内のアイテムが並ぶ方向
### 交差軸
主軸と直角に交わる方向
### text-alignプロパティ
`{text-align: ○○;}`
文章の揃え位置を指定する
### 1つ下の階層の子要素にのみ適用する方法
`○○ □□ {}`
ではなく
`○○ > □□ {}`
にする
deviseでログインする際の項目を追加する

【開発環境】
macOS Catalina
バージョン 10.15.3
ruby 2.5.1
Rails 5.2.4.2
visual studio code
#deviseでログインする際の項目を追加する
deviseでログイン機能を作ると本来はメールアドレス、パスワードだけですが、他の項目のカラムを追加する方法です。

##作成したいカラムを追加
今回は例としてcompanyというカラムを追加します。

```
$ rails g migration AddColumnToUsers company
```
作成されたマイグレーションファイルを見てみます。
デフォルト値の設定をしないとエラーになるそうなので記載します。

```作成日時_add_company_to_users.rb
class AddCompanyToUsers < ActiveRecord::Migration[5.2]
  def change
    add_column :users, :company, :string, null: false, default: ''
  end
end
```

記述が終わったらDBに反映させます。

```
$ rails db:migrate
```

##ビューにフォームを追加する
作成したカラムに値を入力できるようにフォームを追加します。
deviseのビューを作っていない場合は作ります。

```
$ rails g devise:views
```

```registrations/new.html.erb

ここを追加 ---------------------------------
  <div class="field">
    <%= f.label :病院名、会社名を入力してください %><br />
    <%= f.text_field :company, autofocus: true, class: "new_inform"%>
  </div>
---------------------------------
  <div class="field">
    <%= f.label :メールアドレスを入力してください %><br />
    <%= f.email_field :email, autofocus: true, autocomplete: "email", class: "new_inform" %>
  </div>

  <div class="field">
    <%= f.label :パスワードを入力してください %>
    <% if @minimum_password_length %>
    <em>(<%= @minimum_password_length %> 文字)</em>
    <% end %><br />
    <%= f.password_field :password, autocomplete: "new-password", class: "new_inform" %>
  </div>

  <div class="field">
    <%= f.label :パスワードをもう一度入力してください %><br />
    <%= f.password_field :password_confirmation, autocomplete: "new-password", class: "new_inform" %>
  </div>

  <div class="actions">
    <%= f.submit "登録する", class: "new_submit" %>
  </div>
<% end %>
```

##追加したカラムをDBへ反映
ストロングパラメーターの設定でconfigure_permitted_parametersメソッドを使用します。

```devise\app\controllers\application_controller.rb
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

    def configure_permitted_parameters
      devise_parameter_sanitizer.permit(:sign_up, keys: [:company])
    end
```
これでDBに反映することができます。

間違いなどがありましたらご指摘いただければ幸いです。
最後までご覧いただきありがとうございました。
ローカルの画像をCSSで適用する方法

# プログラミングの勉強日記
2020年6月4日　Progate Lv.83
ウェブページ制作中
CSS(`back-ground-image`)で背景画像が表示されなかった。

##background-imageの使い方
　background-image: url( 画像ファイルのURL );
　background-image: url("画像ファイルへのパス");

<font color=blue>urlと半角括弧の間にはスペースを入れない</font>

```html:index.html
<style>
  body{
    background-image:url(photo/S__520912916.jpg);
  } 
</style>
```

<img width="491" alt="0602.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/9cbafcb2-dced-9b75-5d2e-88a320ccec7d.png">

このようにindex.htmlファイルと同じフォルダ内にphotoフォルダがあり、その中の画像ファイルS__520912916.jpgを背景として設定する場合、url()のファイルパス「photo/S__520912916.jpg」となる。


```css:stylesheet.css
/* スタイルシートと同じディレクトリ */
background-image: url("image.png");  

/* スタイルシートから１つ上の階層 */
background-image: url("../image.png"); 

/* スタイルシートから１つ下の階層（今回の場合） */
background-image: url("./photo/S__520912907.jpg");
```
機械学習の統計量を特徴量として加える際のスマートな書き方


数値データの行方向の統計量を特徴量として生成するコードの書き方です。

## ありがちな特徴量生成

まずは良く見る書き方

```Python
# 一個一個付け加えていくやり方
df["sum"] = df.sum(axis=1)
df["max"] = df.max(axis=1)
df["min"] = df.min(axis=1)
df["mean"] = df.mean(axis=1)
df["median"] = df.median(axis=1)
df["mad"] = df.mad(axis=1)
df["var"] = df.var(axis=1)
df["std"] = df.std(axis=1)
df["skew"] = df.skew(axis=1)
df["kurt"] = df.kurt(axis=1)

df.head()
```

これでも良いが、拡張性やメンテナンスを考えるとちょっと気持ち悪い。

## スマートな特徴量生成


```Python
func_list =["sum", "max", "min", "mean", "median", "mad",
            "var", "std", "skew", "kurt"]

for func in func_list:
    df[func] = df.apply(func, axis=1)
    
```

Lambda関数も使える



```Python
f_diff = lambda x: df["xxx"]-df["yyy"]

func_list =["sum", "max", "min", "mean", "median", "mad",
            "var", "std", "skew", "kurt", f_diff]

for func in func_list:
    df[func] = df.apply(func, axis=1)
    
```

---

機械学習ではその場限りの実験が多いので”書き捨て”のコードが量産されがち。
※実際、Kaggleのカーネルなどを見ると結構汚いコードが多い気がする。

なるべくスッキリしたコードを書くと、再利用しやすいし拡張性も高まる。
Rofi でブックマークランチャー

# なんで？

Linux 使ってるといろいろ変わり種のブラウザを試したくなります。ブックマークが無いなんてざらにありますし、ブックマーク機能があっても試し始めではブックマークに何も入っていません。

どんなブラウザを試すときでも自分のブックマークを使えるようにしたいので簡単なトリックで使えるスクリプトを考えてみました。

# 準備

スクリプト本体。gawk を使うのは cut コマンドが良く分かってないからです。

```zsh:lariza_bookmark_rofi
#!/bin/zsh
BOOKMARKS=/好きなところに/bookmarks.txt
case $1 in
  "") BROWSER=firefox;;
  *)  BROWSER=$1;;
esac

URL=$(cat $BOOKMARKS | rofi -dmenu -p bookmark | gawk '{print $2;}')

case $URL in
  "") return;;
  *) $BROWSER $URL  ;;
esac
```

ブックマークファイルはこんな感じで用意

```text:bookmarks.txt
blfs, /sources/blfs/index.html
home, /適当なとろの/LarizaHome.html
gmail, https://mail.google.com/mail/u/0/#inbox
lfs, /sources/lfs/20200319-systemd/index.html
owa, https://outlook.office.com/mail/inbox
tdnet_適宜開示情報, https://www.release.tdnet.info/inbs/I_main_00.html
```

# 使う

``lariza_bookmark_rofi 好きなブラウザ`` で起動します。残念ながらスクリーンショットが撮れませんでした。

# ブラウザ専用のショートカットキーを作る

FVWM 以外だとどうなるのか分かりませんが、FVWM ならコンフィグファイルに

```:~/.fvwm/config
key (lariza) B A M Exec exec lariza_bookmark_rofi OreLariza
key (Firefox) B A C Exec exec lariza_bookmark_rofi firefox
key (otter-browser) B A C Exec exec lariza_bookmark_rofi otter-browser
```

とでもすると、どのブラウザでも ctrl-B で自分だけの rofi ブックマークランチャーが開きます。

# ターミナルが好きなら Peco でも

```zsh:wwwpeco
#!/bin/zsh

BOOKMARKS=~/好きなところに/bookmarks.txt
case $1 in
  "") BROWSER=firefox;;
  *)  BROWSER=$1;;
esac

URL=$(cat $BOOKMARKS | peco | gawk '{print $2;}')

case $URL in
  "") exit;
esac

$BROWSER $URL;
```

![wwwpeco.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248613/3d7eb3d4-bffe-7485-1af7-dda96454b78d.png)

こんな感じで絞り込んで使えます。
【初心者】参照型、値型について整理してみた

#はじめに
プログラムには、値型と参照型というのがあるらしいです。
自分の情報の整理のために書きます。(間違えたことも書いてると思います...)
**例を多く使って整理していきます。**
間違いなど指摘してくだされば、うれしいです...

また、javascript,TypeScript,C#など、ごちゃごちゃに書いてしまっています。申し訳ないです...


[参考サイト1](https://qiita.com/Yametaro/items/45dbfd7f544a69ea7b36)
[参考サイト2](https://dobon.net/vb/dotnet/beginner/valuereference.html)
[参考サイト3](https://ufcpp.net/study/csharp/oo_reference.html)
#値型と参照型
- 値型は、構造体
- 参照型は、クラス

みたいなかんじらしいです。
これだけだと、よくわからないですね...

##値型 の奴ら (よく使うものだけ...)
- int
- double
- float
- number
- bool
- enum


##参照型 の奴ら (よく使うものだけ...)
- クラス(newするやつ)
- 配列
- オブジェクト

#この2つの違いについて
値型と参照型の違いは
**『値型はコピー』**、**『参照型はショートカット』**みたいな感じ。

例で考えた方が分かりやすいので、下記で説明

##値型 (number,int,float...の場合)
```
let num = 0;

change(num);

console.log(num);

function change(num) {
　num = 10;
}
```
`change`メソッドの引数に、変数`num`をわたして
`console.log`で変数の中身を見てみると、

`num = 0`

になりますね。
変数の中身のコピーを`change`メソッドの引数に渡しただけなので変化なしです
では、次...
##参照型 (配列の場合)
```
let numArr = [0, 1, 2];

change(numArr);

// "numArr = [10, 1, 2]"
console.log(numArr);

function change(numArr) {
　numArr[0] = 10;
}
```
`change`メソッドの引数に、変数`numArr`をわたして`console.log`で中身を見てみると、

`numArr = [10, 1, 2]`

になります。
！？って感じでした...
予想では
`numArr = [0, 1, 2]`
だったのに...

先ほども言ったように、参照型である配列は
変数に入れた時、変数は中身のショートカットのような扱いになります。

**『ショートカットのような扱い』**をもっと分かりやすく説明すると
下記のような感じになります。

```
let arr0 = [0, 1, 2];
let arr1 = arr0;
let arr2 = arr1;

arr2[0] = 10;

console.log(arr0);
console.log(arr1);
console.log(arr2);
```

これも私の予想では
`arr0 = [0, 1, 2]`
`arr1 = [0, 1, 2]`
`arr2 = [10, 1, 2]`
でしたが、
実際に動かすと...

`arr0 = [10, 1, 2]`
`arr1 = [10, 1, 2]`
`arr2 = [10, 1, 2]`

でした...


変数`arr0`の中身を、変数`arr1` `arr2`に入れると
中身は共通のものになるんですね...

配列を使うときは気を付けたいです...

##じゃあこの場合はどうなるのか...？
さっきまでは、`arr[0] = 10;`のように配列の**中身**を変えていました

では、次の場合にはどうなるんだろう..

```
let arr0 = [0, 1, 2];
let arr1 = arr0;
arr1 = [10, 1, 2];

console.log(arr0);
```
これを実際に動かすと、`console.log`では

`arr0 = [0, 1, 2]`

と出ます。

この場合は、
『配列の中身を変える』
ではなく、
**『新しい配列に入れ替える』**
っていう感じになるのかなと思いました。


#まとめ
配列やクラス(とくに配列)を使うときは、値型のように使わないように気を付けないと...
というのが、学べました。

値型と参照型、それぞれの特徴をもっと理解すれば、もっと上手にプログラムを組めるのかなと思います...
値型や参照型について、さらに詳しいことを知っている方がいましたら、コメントなどで教えていただけると嬉しいです。
C++ ムーブコンストラクタとムーブ代入演算子

「コピーコンストラクタ＆代入演算子」と「ムーブコンストラクタ＆ムーブ代入演算子」を区別できるようになったので、感動のあまりメモします。

- ムーブコンストラクタがあるとSTLコンテナの`push_back`と`std::move`で譲渡によるコピーと想定外のデストラクタ呼び出し回避が可能です。
- コピーコンストラクタ（const参照のコピーコンストラクタ）はコピーのコストがありますが、ムーブコンストラクタはありません。

|C++の特別なコンストラクタ|構文|概要|
|:--|:--|:--|
|デフォルトコンストラクタ|`Class()`|引数なし。|
|コピーコンストラクタ（const参照）|`Class(const Class& r)`|元のオブジェクトは変更されないので`const`。|
|ムーブコンストラクタ|`Class(Class&& r)`|元のオブジェクトは移譲されるので非`const`。初期化時に`std::move`を与えることで呼び出せる。|

|C++の代入演算子オーバーロード|構文|概要|
|:--|:--|:--|
|（コピー）代入演算子（const参照）|`Class& operator=(const Class& r)`|元のオブジェクトは変更されないので`const`。|
|ムーブ代入演算子|`Class& operator=(Class&& r)`|元のオブジェクトは移譲されるので非`const`。|

より詳しく分かりやすい情報源：
[右辺値参照・ムーブセマンティクス - cpprefjp C++日本語リファレンス](https://cpprefjp.github.io/lang/cpp11/rvalue_ref_and_move_semantics.html)
[Unity]Motion Blurで勘違いしてたこと・続 ～Post Processing Stack ゴメンナサイ。でもダメ～

 **[前回の記事](https://qiita.com/flankids/items/cd451246ee044a3f809a)** で、

> Post Processing Stack の Motion Blur は、カメラの角度や座標の変化によって画面はブレますが、カメラが不動・あるいはあまり動かないときに、 視野内でオブジェクトがどんなに激しく動こうとモノがブレない

と書きましたが。間違いでした。

# ブレました
![ブレる.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184294/82106e7f-75af-44a6-0ae4-32adbaf0478a.gif)
▲ブン・・・ブン・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184294/f83ad6e7-8fa7-d332-0c80-613f206df3ac.png)
Post-Processing Profile の Motion Blur の **「Frame Blending」** という値を、0より大きい値にすることで実現できました！

でも、ちょっと違うんです。コレじゃなかったんです。

# 何が気に入らないの？
まず、 **カメラを動かしてブレさせたとき** の絵をご覧ください。
![blur_1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184294/d5e4ac72-f303-0e60-555f-8dcbf7af505a.jpeg)
輪郭がボヤけるような感じになっていて、リアルなブレ方になっているのがわかります。

一方、 **「Frame Blending」を使ってオブジェクトを動かしてブレさせたとき** の絵がこちらです。
※中央のブロックに注目してください。
![blur_2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184294/0a556fa9-6d33-de33-9745-f3e326ea4172.jpeg)
フレーム感を補間してるに過ぎないので、ブレてはいるんですが **輪郭がはっきりした残像** が遅れて消えてるに過ぎず、イマイチきれいなブレ方ではありません。

# 理想

<img width="500" alt="モーションブラー_2.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184294/c980b882-dfb9-0a5f-dd56-474f6b982399.jpeg">

やはりこちらを持ち出しますが、やはり輪郭がぼやけるようなブレ方・・・というより **色が動きの線上に伸びるようなブレ方** にしたいなと思っていて、それにはやはり前述のカメラを動かしたときのようなブレ方が望ましいのです。

引き続き調べます。

ちなみにゼノブレイドリメイク版はサブクエストしすぎてまだモナドもらってません。

# 試してみようと思ってるやつ
会社で **[良さげなGitHub](https://github.com/keijiro/KinoMotion)**  を共有していただいたので、これを試してみようと思います。
デモを見たところ、望んでる絵になってそう・・・！
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">I continue testing the motion blur effect.<a href="https://t.co/weJyKnr6l9">https://t.co/weJyKnr6l9</a> <a href="https://t.co/L0CMlfCNW3">pic.twitter.com/L0CMlfCNW3</a></p>&mdash; Keijiro Takahashi (@_kzr) <a href="https://twitter.com/_kzr/status/738726928362807297?ref_src=twsrc%5Etfw">June 3, 2016</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
constあるある：「オブジェクトにメンバ関数と互換性のない型修飾子があります」を解消する

#頻発ミス

VisualStudioで、こんなErrorが出たことはありませんか？
　**オブジェクトにメンバ関数と互換性のない型修飾子があります**

ちょっと例を出してみましょう。

```Sample.h

class Sample
{
private:
    int member_;

public:
    // constructorとかsetterとかは省略しています. 
    Sample(const Sample& argSample);
    int getMember();
};
```

```Sample.cpp
#include "Sample.h"

Sample::Sample(const Sample& argSample)
{
    member_ = argSample.getMember();
}

int Sample::getMember()
{
    return member_;
}
```

・・・さて、こんな感じのコードだと、イントロにあるようなErrorが出てきてしまいます。
原因は一体何でしょうか？

#Errorの原因

このメンバ関数では「const参照渡し」をしていますね。

```Sample.h
    Sample(const Sample& argSample);
```

```Sample.cpp
Sample::Sample(const Sample& argSample)
{
    member_ = argSample.getMember();
}
```

・・・ん？
このメンバ関数があかんことになっていますね。

```Sample.h

    int getMember();
```

```Sample.cpp

int Sample::getMember()
{
    return member_;
}
```

そう・・・「const修飾子」が無いのです！
constオブジェクトからは、constメンバ関数しか呼び出すことができません！

#const修飾子

const 修飾子を使う目的は「値を書き換えられなくする」ということです。
　・変数：値が変更できなくなる

```変数.
// 宣言の先頭につける. 
const int MAGIC_NUMBER = 10; 
```

　・関数：呼び出したオブジェクトの持つメンバ変数を変更できなくなる

```関数.
// 宣言の末尾につける. 
int getNumber() const; 
```

※変数、関数いずれもクラスのメンバという前提です

constオブジェクトから呼び出せるのは、constメンバ関数だけです。
　OK：constメンバ関数
　NG：非constメンバ関数

#Errorの解決法

ということで、Errorの原因となっているメンバ関数に「const修飾子」をつけます。
※末尾につけること！

```Sample.h

    int getMember() const;
```

```Sample.cpp

int Sample::getMember() const
{
    return member_;
}
```

「const参照渡し（const参照返しもかな？）」は非常によく使う手法です。
それだけに頻発するErrorなのではないかと思います。
「const参照渡し」を使う時には
　「渡したオブジェクト（参照）から呼び出すメンバ関数って、ちゃんとconstついてるかな？」
ということを気にしてみて下さい。
なぜ？ec2インスタンスの踏み台サーバ経由のSSH接続がうまくいかない

# TL;DR
接続したいサーバーのホスト名にパブリックIPを指定していた、プライベートIPの間違いでした
気づくのに３時間ほどかかった分、ProxyCommandとかｓｓｈの設定に関して理解が深まっていい経験になりました😇

# やりたかったこと
パブリックなサブネットに踏み台用のec2インスタンスを作成して、プライベートなサーバにsshがしたい！
多段sshは初めてなので見様見真似でやってみる

ProxyCommandなるものを使うらしいので、こちらの記事を参考に.ssh/configを修正
[踏み台サーバーを経由してSSH接続する設定を~/.ssh/configに書く
](https://qiita.com/FukumotoRyota/items/09c15baff05e3e24e946)
# 症状

.ssh/configは以下のように設定

```
Host humidai
User ec2-user
HostName 踏み台サーバのパブリックIP
IdentityFile ~/.ssh/秘密鍵のファイル名.pem

Host honnmei
User ec2-user
HostName 接続したいサーバのパブリックIP 
IdentityFile ~/.ssh/秘密鍵のファイル名.pem
ProxyCommand ssh humidai -W %h:%p 
```

ssh honnmei　とすると

```
channel 0: open failed: connect failed: Connection timed out
stdio forwarding failed
kex_exchange_identification: Connection closed by remote host
```

。。。🙃

こちらを参考にいろいろ試行錯誤
[ssh_exchange_identification: Connection closed by remote host エラーが発生した時の対処]
(https://rinoguchi.hatenablog.com/entry/2019/10/09/142038)

しかし一通り検証したが解消できず、、、投げたい

# 原因
途方にくれた末にこちらの記事にたどり着く
[【AWS 再入門】VPC 環境に踏み台サーバーを構築して SSH 接続してみよう]
(https://tech.recruit-mp.co.jp/infrastructure/retry-aws-bastion-host-vpc/)

>Hostnameにはアプリサーバーインスタンスに割り当てられているPrivate IPsを指定すればOKです。


あ。。。

さっそく
.ssh/configのHostName部分を修正

```
ユーザー@usernoMacBook-Pro-5 ~> ssh honnmei

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

https://aws.amazon.com/amazon-linux-2/
[ec2-user@ip-*.*.*.* ~]$
```
どっつかれた〜〜
○ヶ月から、○年○ヶ月に変換する

#概要
月数から、年数と残りの月数を求める方法です。（Javaで書いてます）

```
35ヶ月は2年11ヶ月です
```

このような感じ。

#変換方法

コードはこんな感じ。

```YearMonth.java
public class YearMonth{
    public static void main(String args[]){
        int monthCount = 35;
        System.out.println(monthCount + "ヶ月は" + monthCount/12 + "年" + monthCount%12 + "ヶ月です");
    }
}
```

変数monthCountに格納された35ヶ月が、年月に変換されています。

年とヶ月は別々で計算しました。

年の方は、35ヶ月を12ヶ月（1年）で割り、Math.floorで小数点を切り捨て。
そしてそのままだと小数点が.0と付いてしまったので、前に(int)を置いて整数に。

ヶ月の方は、35ヶ月から12ヶ月（1年）を割った余りにすることで計算できました。
nginx の rewrite で古いドメインを新しいドメインに移行する

サイトを運用していて、途中からドメインを変更したい場合があります。nginx の rewrite を使うと簡単に移行が出来ます。

## rewrite によるドメインの移行

http://old.example.com/index.html -> http://new.example.com/index.html

という様に飛ばしたい場合：

```
server {
    listen       80;
    server_name  old.example.com;

    rewrite ^ $scheme://new.example.com$request_uri permanent;
}
```


と設定します。ここで `$request_uri` はドメインより後ろの文字列で、ドメインだけを書き換えて同じページに飛ばすことが出来ます。単にトップページに飛ばすのではなく、対応するページに飛ばすことが出来ます。

```
rewrite ^ $scheme://new.example.com$request_uri permanent;
# or
rewrite ^(.*)$ $scheme://new.example.com$1 permanent;
```

上記の二つは、意味的には等価になりますが、前者の方が正規表現を使わない分、パフォーマンスが良くなります。

## rewrite による www の削除

nginx の rewrite は結構便利で数行書くだけで、色々なことが出来ます。例えば、アドレスに `www` が要らないなと思うなら、この様に書くことで、`www` を取り除くことが出来ます：

```
server {
    listen       80;
    server_name  www.example.com;

    rewrite ^ $scheme://example.com$request_uri permanent;
}
```

## rewrite による https の強制

以下のように、https を強制するのにも使えます：

```
server {
    listen       80;
    server_name  example.com;

    rewrite ^ https://$host$request_uri permanent;
}
```

## 参考

* http://ec2-54-248-216-128.ap-northeast-1.compute.amazonaws.com/blog/2013/useful-rewrites-for-nginx/
[Kubernetes]Init Containersの動作を確認する

#はじめに
今回はInit Containersの動作を確認したいと思います。
Init Containersとは、アプリケーションコンテナの前に実行され、アプリケーションコンテナのイメージに存在しないセットアップスクリプトやユーティリティーを含んだ特別なコンテナです。

ユースケースとしては、セキュリティの観点でアプリケーションコンテナイメージに含めたくないツールの実行などがあります。
そのほか、以下のマニュアルにも記載されています。


>[Initコンテナは何に使用できるか?](https://kubernetes.io/ja/docs/concepts/workloads/pods/init-containers/#init%e3%82%b3%e3%83%b3%e3%83%86%e3%83%8a%e3%81%af%e4%bd%95%e3%81%ab%e4%bd%bf%e7%94%a8%e3%81%a7%e3%81%8d%e3%82%8b%e3%81%8b)

#設定
では、実際にInit Containersを実行してみたいと思います。ここではInit Containersを利用して、nginxのindex.htmlファイルを作成しています。
なお、Init Containersは複数設定することもできます。

```initContainer.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-init
  labels:
    app: app1
spec:
  initContainers:
  - name: init01
    image: centos:latest
    args:
    - /bin/sh
    - -c
    - echo "test" > /test/index.html
    volumeMounts:
    - mountPath: /test
      name: nginx-index
  containers:
  - name: nginx
    image: nginx:latest
    volumeMounts:
    - mountPath: /usr/share/nginx/html/
      name: nginx-index
  volumes:
  - name: nginx-index
    hostPath:
      path: /test
      type: Directory
```

この設定を図にすると、以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/e6502dab-849a-8bf9-9c8a-13181b7674b8.png)

* Init Containesの初期化処理で、マウントしたボリュームにindex.htmlファイルを作成します。
* 初期化処理が終わったらアプリケーションコンテナを起動し、index.htmlファイルを作成したボリュームにマウントします。

#動作確認
上記のマニフェストをapplyします。このとき、別ターミナルでPodの状態を確認します。

```
$ kubectl apply -f initContainer.yaml
pod/nginx-init created
```

```
$ kubectl get pod -w
NAME         READY   STATUS    RESTARTS   AGE
nginx-init   0/1     Pending   0          0s
nginx-init   0/1     Pending   0          0s
nginx-init   0/1     Init:0/1   0          0s
nginx-init   0/1     Init:0/1   0          1s
nginx-init   0/1     PodInitializing   0          5s
nginx-init   1/1     Running           0          9s
```

PodがRunningになる前に、Init処理が実行されていることがわかりますね。

外部サーバからアクセスして確認します。LoadBalancerは作成済みです。

```
$ kubectl get svc
NAME            TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)          AGE
kubernetes      ClusterIP      10.96.0.1       <none>         443/TCP          103d
load-balancer   LoadBalancer   10.111.156.47   10.20.30.150   8080:30002/TCP   5d22h
```

```
[client]$ curl -s http://10.20.30.150:8080
test
```

Init Containersで作成したindex.htmlでリクエストが返ってきていますね。

#まとめ
今回確認したInit Containersを利用すると、前処理として色々な処理ができますね。
Kubernetesの基本から応用に入ってきてると思いますが、アプリ寄りの考え方がますます必要になってきてるなと感じています。インフラ屋さんと言えど、避けては通れないですね。がんばらないと。
ABC 062 D   3N Numbers　

##問題
https://atcoder.jp/contests/arc074/tasks/arc074_b
N を 1 以上の整数とします。
長さ 3 N の数列 a = ( a 1 , a 2 , . . . , a 3 N ) があります。 すぬけ君は、 a からちょうど N 個の要素を取り除き、残った 2 N 個の要素を元の順序で並べ、長さ 2 N の数列 a ′ を作ろうとしています。
このとき、 a ′ のスコアを ( a ′ の 前 半 N 要 素 の 総 和 ) − ( a ′ の 後 半 N 要 素 の 総 和 ) と定義します。 a ′ のスコアの最大値を求めてください。
##見た感じ
中間のn個の間全部に仕切りを入れて、その左と右で数がnになるまで数字を捨てていけば計算できると思ったけど、最初は$O(k^2)$かかるやんって思っていた。（priority_queueの練習問題としってて。。）
でもよくよく考えると、区切りを一つ右に動かしたとき、候補は一つしか増えず、消すべき要素数も一つ増えるので、仕切りを動かすたびに仕切りの左側については最小値を更新して抜いていけば、それで仕切りの左側での和の最大値は求まっているし、仕切りの右側も同様だった。
だから、左側、右側を両端からpriority_queueを使って、最小値、最大値を逐次抜いていき、最後に仕切りの場所同士で最大の場合を選べばよい。
##解法
逐次priority_queueを使って最大値、最小値を更新していき、最後に全体の最大値を求める。
Nの三倍配列を用意していないといけないことに注意。。。
##ソースコード
```c++
const int N_MAX=3000015;
priority_queue<ll> a;
priority_queue<ll,vector<ll>,greater<ll>> b;
ll n,suma[N_MAX],sumb[N_MAX],r[N_MAX];

int main(){
    int x,y;
    //入力
    cin>>n;
    rep(i,3*n){
        cin>>x;
        r[i]=x;
        if(i<n){
            sumb[0]+=x;
            b.push(x);
        }else if(i>=2*n){
            suma[0]+=x;
            a.push(x);
        }
    }
    //処理
    int blim=n-1,alim=2*n;
    ll resb,resa;
    rep1(i,n){
        b.push(r[blim+1]);
        resb=b.top();b.pop();
        blim++;
        sumb[i]=sumb[i-1]+r[blim]-resb;
        
        a.push(r[alim-1]);
        resa=a.top();a.pop();
        alim--;
        suma[i]=suma[i-1]+r[alim]-resa;
    }
    ll ans=-1*INF18;
    rep(i,n+1){
        ans=max(ans,sumb[i]-suma[n-i]);
    }
    //出力
    cout << ans <<endl;
}
```
pythonでソートアルゴリズム -挿入ソート

# はじめに
プログラミング初心者がソートアルゴリズムを自分なりに理解し、コーディングしてみたものの忘備録になります。
間違いもあるかもしれませんがご了承ください＆ご指摘いただけると助かります…。
ここでは**挿入ソート**を扱います。
参考にした本と記事はこちら
→https://www.codereading.com/algo_and_ds/algo/
→https://book.impress.co.jp/books/1118101057


# 挿入ソート
元ある配列の頭から、新しい配列に並び替えつつ挿入していくソートアルゴリズム。
全比較を行うバブルソートや選択ソートと違い、**挿入できる箇所を見つければそこで終了**するので、**比較回数の平均値が少なく**なります。


## 手順

![各ソート.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614239/15abca80-b91a-eb61-c28f-120a717bd2d5.jpeg)


## 比較回数
### 最大値
```math
1+2+...+(n-1) = \sum_{k=1}^{n-1} k = \frac{1}{2}n(n-1) 
```

## プログラム
```python:insertion_sort.py
a = [4,6,1,2,3,8,5]

# 1番最初の値は挿入済みとし、0ではなく1から始める
for i in range(1, len(a)):
    # 挿入したい値がすでにa[i]に入っているという感覚でスタート
    for j in range(i, 0, -1):
        # 挿入個所の手前にある数字が挿入した数字より小さい場合
        if a[j] < a[j-1]:
            # 値をひっくり返して配列の頭のほうに攻めていく
            a[j-1], a[j] = a[j], a[j-1]
        # ひっくり返す必要がなくなった時点で、for文を抜け出す
        else:
            break
print(a)
```

## 計算量
for文を2重に回すので、**O(n^2)**となるが、前述のとおり同じ計算量のバブルソートや選択ソートより効率がよくなる。

# おわりに
手順は描くよりつくったほうが早くてきれいでいいですね。
ソートは手を動かして書いたほうが理解がしやすくて良いです。
シェルソート、クイックソート、ヒープソート、マージソートについては書きたいです…。
[メモ]WANについて

WANについての覚書
# WANとは
WAN（Wide Area Network）本社 ⇔ 支社間などサイト間のLANを相互に接続するネットワーク

# WANを実現する主なサービス
- 広域イーサネット
- IP-VPN
- インターネットVPN
- 専用線

### 提供事業者例
[Arcstar Universal One](https://www.ntt.com/business/services/network/vpn/vpn.html)
[フレッツ・VPN プライオ](https://business.ntt-east.co.jp/service/vpnprio/)

## 広域イーサネット
- L2で動作
- 閉鎖網を利用
- ルーティングプロトコルはスタティック、BGP、RIP、OSPFなど使用可
- 送信プロトコルはIP以外も利用可
- 金融、メディア、通信業などネットワークの重要性が高くカスタマイズが必要な場合に使われる事が多い
- バックボーンでは802.1qトンネリング(VLAN)を使用する。
- 暗号化はされない

## IP-VPN
- L3で動作
- 閉鎖網
- 送信プロトコルはIPのみ使用化可
- ルーティングプロトコルはスタティックまたはBGPのみ使用可
- 製造、流通、サービス業など高度な設定が必要がない場合に使われることが多い
- バックボーンではMPLS( Multi Protocol Label Switching )を使用する。
- 暗号化はされない

## IP Sec-VPN
### トンネルモード
- ルーター間での暗号化
- 元のIPは暗号化され新しいIPヘッダが付与される(VPNゲートウェイのIPアドレスが付与される)

### トランスポートモード
- ホスト間で暗号化される
- L4以上のデータを暗号化

## インターネットVPN
- インターネット経由で拠点間の通信を暗号化

### リバースプロキシ
- ブラウザーから利用(ブラウザーでSSL化)
- Webブラウザーに対応していないアプリケーションは利用不可

### ポートフォワーディング
- 要モジュールダウンロード(モジュールでSSL化)
- ポートが固定されている必要があるのでFTPなどのアプリケーションは使えない

### L2フォワーディング
- 要モジュールダウンロード(モジュールでSSL化)
- モジュールの仮想NICにVPN装置で設定された企業イントラネット内のIP アドレスがに割り当てられる
MySQLのインストーラーが途中で停止する問題の解決

Railsでアプリケーションを久しぶりに作ろうとした際にMySQLに関連したエラーが出たので、一度MySQL（MySQL Community Server 8.0.15）を再インストールする事にしました。 

しかし、アンインストール後に再度インストールしようとするとインストーラーが途中で止まってしまう問題が発生した為、下記の通り色々な試みを行いなんとかインストールに成功したのでメモしておきます。


したこと。
・MySQLアンインストール後に残っていたゴミファイルの削除（Program Files、ProgramData内のファイルを消したり、環境変数のPATHにある欄を消す等）
**→ 解決せず**


・様々なバージョンのMySQLを試す
**→ 解決せず**

・Visual C++ 再頒布可能パッケージを全て削除し、2013年版、2015年版、2015年版～2019年版を改めてインストール
**→ 解決しました**

本来Visual C++ 再頒布可能パッケージが欠けている場合はインストーラーからさらに先に進んでランチャー起動時に警告されるのが普通のようですが、どういうわけか今回はインストーラー起動時に発生してしまい解決までに数時間掛かってしまいました。 またインストーラーで停止する問題はいくら検索しても全くヒットしなかったのでかなり特殊な環境でないと起こらないのではないかと思います。 こういう時が一番やっかいですね…。 恐らくアンインストールに不備があったのだろうと思います。
【機械学習】時系列データでのトレーニング/テストデータの作成で注意すべきこと

#はじめに
トレーニングデータ、テストデータに分割するときに、テストデータにトレーニングデータを含ませないのは機械学習の基本です。

しかし、時系列データだとその間違いは気付かないうちに起きやすいので、簡単に図でまとめてみました。

今回は、予測対象日から1日前〜3日前のデータを用いて予測するというケースについて考えます。

分かりやすさを考え、予測対象のデータ（目的変数）と予測に使うデータ（説明変数）は別種類のデータとし、さらに説明変数を１種類としました。

#ダメな手順の例
1. 予測に使うデータ（説明変数）を1〜3日分ずらし、1日前〜3日前の説明変数を作成する
2. トレーニングデータ、テストデータに分割する

この順番に行うとどうなるでしょうか。

もちろん目的変数も時系列で変化しますが、注目すべき説明変数にアルファベットを付けました。

1の操作を行うと次の図のようになります。
![06E6B9CA-4E42-4C58-9ED1-A0D6D43459BA.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429131/cda5bd23-b734-efd7-fb13-4daab36e2124.jpeg)
エクセルの表のように時系列で並んでいるとお考えください。

さて、ここで2の操作を行うとどうなるでしょうか。
![7C0D71B2-0F21-4E7C-8231-4410220AD40C.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429131/83c28732-adc0-7dc3-b19f-b63f69683709.jpeg)

（さすがにこんなところで分けることはないですが簡略化ということで・・・）

この後、欠損値を含む列を削除したとすると、確かに３日分の説明変数を用いて予測できそうです。
しかし、この説明変数をよくみると、トレーニングデータで使われてるBとCの値がテストデータにも含まれてしまっていることがわかります。これではダメですね。

#正しい手順の例
これはずばり、ダメな手順の例の反転です。

1. トレーニングデータ、テストデータに分割する
2. 予測に使うデータ（説明変数）を1~3日分ずらし、1日前〜3日前の説明変数を作成する


こうして作成されるデータは次の図のようになります。
![DBF32EE6-1E4B-4A8C-A7D8-DDFCADA342DD.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429131/015dcebc-c94e-e926-f0a1-03dfdd78c97a.jpeg)

これでトレーニングデータとテストデータが重複なく分けられました！

分割してからずらしたため、欠損値がダメな手順より増えることになります。

欠損値がある列は削除するなどして、前処理を加えたあとモデル作成へと進んでください。
[C++]Effective C++ 第3版 2項

# About me
この物語は、**C言語からC++に進化したいエンジニア**の平凡な**考察**を淡々と描くものです。過度な期待はしないでください

# #defineより、const,enum,inlineを使おう
defineは作った人にしかわからない。例えば円周率を親切に#defineしてくれても、ここで使っている円周率は、果たして3.14なのか3なのかいちいち見ないとわからない。
今はエディタが発達して、簡単に変換してくれるが結果見に行くことには変わりはない。なんであえて参照させるのか、複雑な#defineを書いてくれる人がいるが解読に時間が掛かる。#defineは嫌いだ。

#提案
では、どうすればいいのか。円周率の定数を使うときは、
 　#define PI 3.14
 　→const double PI = 3.14

ちなみにconstについて、定数なのでROM領域に配置される。#defineはプリプロセッサで置き換えられて、多分必要ならばコンパイラが先に計算までしてくれる。constもvolatileつけなければ計算してくれるかもしれないが・・・。

さて、ポインタを扱う場合constは2つつけることができることにお気づきだろうか？1つはアドレスが固定。もう一つは値が固定。
では、ポインタのポインタには、constを3つつけることができるのかというと、つけらないのではないかと考えているが、よく知らない。

const *char const name = "Bayashi"

アスタリスクの左のconstは値が固定
アスタリスクの右のconstはアドレスが固定

#さらなる利点
CからC++に移ると理解しなければいけないのは、スコープの概念だ。Cにもあるにはある。グローバル変数とローカル変数だ。つまりどこでも使える変数と｛｝内でしか使えない変数の違いだ。
C++ではそれに加えてクラスの概念があるので、クラスのスコープを持つことができる。前置きはこのへんで、グローバルなものは危険極まりない。どこで何が起こるか、どんな重複が起こるのか分かったものではない。
 #define 黒いカラス 白いカラス 
と書かれたら、世界中のカラスを白く塗り上げないといけなくなる。きもちわるい思考だ。
でもクラスに保坂がいたとしたらどうだろう。その影響範囲は保坂の中だけなんだ。

#enum　#defineの代わりにする
enumは全然使い道分かっていなかったけど、自由度を下げる役割がある。そのうち説明しよう。constな変数のアドレスを使用することは許されるがenumはとにかく頑固者だ。だからミスが少ない。


#　inline　を #define代わりにする。
大きい方を使って関数を呼び出すマクロ　作ったよ
　#define Witch_Big(a,b) func((a)>(b) ? (a):(b))

ここで a,bがただの数値ならいいけど
　++aなんてやったら、funcが呼び出されるときaの値インクリメントされているけど大丈夫？となる。

でもそんな課題もinlineとテンプレートで解決できる。

template<typename T>
inline void Witch_Big(const T& a, const T& b)
{
  f(a>b ? a : b)
}

aもbも参照を使っているので、引数が複数回評価されることはない。
【GAS】Googleフォームからの問い合わせをスプレッドシートで管理し、未回答のものだけメール送信する

# はじめに
Googleフォームで依頼を受け、対応後、スプレッドシートに記入したらメールを送信したい場合のコードです。

処理の流れとしては以下
この記事は、４の内容のコードです

1. Googleフォームで依頼を受ける
2. オフラインで対応
3. 2の対応後、対応した内容スプレッドシートに記入する
4. 3の対応済み、かつメール送信していないものを1の問い合わせ者に通知する


紫色項目が、Googleフォームからの問い合わせ
青色項目が、手動記入＆GASで使うステータス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14760/c59f3c0f-5f0d-f7ff-244c-866926d21d3a.png)


| タイムスタンプ | test | test1 | メールアドレス | Ans | 送信ステータス |
|:--|:--|--:|:--|:--|--:|
| 2020/06/04 21:33:02 | a | 1 | xxx@gmail.com | Ans記入 |  |

# コード
```javascript
function myFunction() {
  // スプレッドシート取得
  let sheet = SpreadsheetApp.getActive().getSheetByName('フォームの回答 1');

  // データ取得範囲指定
  const row = 2;
  const column = 1;  
  const LastRow = sheet.getDataRange().getLastRow();
  const LastColumn = sheet.getDataRange().getLastColumn();
  const numRows = LastRow - row + 1;
  const numColumns = LastColumn - column + 1;

  // データ取得
  let data = sheet.getRange(row, column, numRows, numColumns).getValues();

  
  // メール
  let recipient = ''; // 送信先メールアドレス
  let subject = '対応完了 - '; // メール件名
  let body = '';
  let sendCnt = 0;
  
  for (let i=0; i < data.length; i++) {
  // １行ずつメール未送信かどうかチェック
    if ( data[i][5] != '済' ) { // 送信ステータスチェック
      recipient = data[i][3];
      subject += data[i][1];
      body += '\ntest:' + data[i][1];
      body += '\ntest1:' + data[i][2];
      body += '\nAns:' + data[i][4];

      GmailApp.sendEmail(recipient, subject, body); //, options
      
      sheet.getRange(i+2, 6).setValue('済');
      
      sendCnt ++;
    }
  }
  
  if ( sendCnt == 0 ) {
   console.log('送信対象無し'); 
  }
}
```


# 参考
* [【初心者】GoogleAppsScriptでGoogleスプレッドシートを操作する基本コード ベスト3](https://qiita.com/Shin/items/ef504b2fee00789e2f4b)
* [【初心者】GASで、Webスクレイピング, スプレッドシート保存, メール送信するコード](https://qiita.com/Shin/items/e86ec7d28ddbb340f793)
Elasticsearch の plug-in のサイトをxpathを使用して検索＆表示してみる

#目的
Windows10 + Python3 + selenium + chromedriver + headless chrome で Elasticsearchの plugin 用のサイトをアクセスしてみる
Fessのメンテや新規インストール時にElasticsearchのpluginのバージョンチェックが楽にできないかな？
とりあえずのテストコードを作成
※仕様は未定 plugin は決め打ちなので直接みに行けばいいんじゃないかと
[org/codelibs](https://repo1.maven.org/maven2/org/codelibs/)をローカルに保存してテストを行う
#サンプルコード

```python
# Windows Add env PYTHONIOENCODING = UTF-8 & restart vscode

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options
import chromedriver_binary

# plugin のリスト
alist = [
    'elasticsearch-analysis-extension/',
    'elasticsearch-analysis-fess/',
    'elasticsearch-configsync/',
    'elasticsearch-dataformat/',
    'elasticsearch-minhash/'
]

# ブラウザーを起動
options = Options()
options.binary_location = 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe'
options.add_argument('--headless')
driver = webdriver.Chrome(options=options)

# driver.get('https://repo1.maven.org/maven2/org/codelibs/')
# 上記をローカルに保存
driver.get('http://localhost:8080/codelibs.html')

try:
    element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.TAG_NAME, 'a'))
    )

    # xpath はこれで良いのだろうか？
    xpath = "/html/body/main/pre/a"
    elems = driver.find_elements_by_xpath(xpath)
    
    # listに存在する link text を表示する
    for elem in elems:
        if elem.text in alist:
            print(elem.text)

finally:
    print('done')
    driver.quit()
```
#参考にしたサイトはこちら
[WebElement 内部を find_element_by_xpath() で再検索した時のつまずき](https://qiita.com/ttn_tt/items/948b4c9f03c1460504b9)
[Python/Seleniumで便利なxpath検索をする方法！](https://watlab-blog.com/2019/08/12/selenium-xpath/)
C++ STL basic_string_viewの使いたい場合、使えない場合

C++17からSTLに`std::basic_string_view`が追加されました。これを使えば文字列やSTLコンテナのコピーによる無駄な演算やメモリ消費を防ぎ、さらに共通インターフェイスを提供できます。

## `std::basic_string_view`を使いたい場合

1. 参照するデータの寿命がビューの寿命より長い場合。
1. 文字列リテラル、STL文字列、文字型のSTLコンテナに共通インターフェイスを提供する場合。
1. バイナリデータの一部を文字列として扱う場合。
1. 関数の引数に使う場合。

`std::basic_string_view`は文字列リテラル、STL文字列（`std::basic_string`）、文字型のSTLコンテナ（`std::vector<char>`等）に対して、共通の文字列ビューを提供します。文字列リテラルの場合は`std::string_view_literals`名前空間のサフィックス`sv`も使用できます。

```cpp
#include <vector>
#include <string_view>
#include <iostream>

// サフィックスsvの使用に必要です。
using namespace std::string_view_literals;

int main()
{
	std::wstring ws = L"ABCDE";
	std::vector<wchar_t> v = {'A','B','C','D','E'};

	// どの方法でも文字列ビューを作成できます。
	std::wstring_view wsv1(L"ABCDE");
	std::wstring_view wsv2 = L"ABCDE"sv;
	std::wstring_view wsv3(ws);
	std::wstring_view wsv4(v.data(), v.size());

	// starts_withメンバ関数はC++20以降です。
	std::wcout << wsv1.starts_with(L"ABC") << std::endl; // 1
	std::wcout << wsv2.starts_with(L"ABC") << std::endl; // 1
	std::wcout << wsv3.starts_with(L"ABC") << std::endl; // 1
	std::wcout << wsv4.starts_with(L"ABC") << std::endl; // 1

	return 0;
}
```

文字列やSTLコンテナのサイズが小さい場合は`std::basic_string`でも大差ありませんが、サイズが大きい場合は`std::basic_string_view`の使用が推奨されます。

例えば1 GBのテキストファイルをコピーするとき、`std::basic_string`は回数分だけ1 GBのメモリ確保やコピーが発生します。こんなサイズは使わないと思いますが、100 MBの文字列を10回コピーすれば1 GBのコピー1回分です（メモリ使用量は使い方に依存します）。

また、バイナリデータ（バイト配列）として読み込んだファイルの一部を文字列として扱う場合にも`std::basic_string_view`が便利です。

## `std::basic_string_view`を使えない場合

1. 参照するデータの寿命がビューの寿命より短い場合。
1. 特に関数の戻り値から外れる場合。

`std::basic_string_view`はアドレスとサイズしか保持しないので、参照元のデータが解放されると不正なメモリを参照します（ダングリングポインタ）。

```cpp
#include <string>
#include <string_view>
#include <iostream>

// サフィックスsの使用に必要です。
using namespace std::string_literals;

std::wstring f()
{
	std::wstring ws = L"ABCDE";
	return ws;
}

int main()
{
	// wsの寿命が先に終わるのでwsv1はダングリングポインタ
	std::wstring_view wsv1;
	{
		std::wstring ws = L"ABCDE";
		wsv1 = ws;
	}
	std::wcout << wsv1 << std::endl;

	// fの戻り値（std::wstring型）が代入後に解放されて
	// wsv2はダングリングポインタ
	std::wstring_view wsv2 = f();
	std::wcout << wsv2 << std::endl;

	// L"ABCDE"s（std::wstring型）は代入後に解放されて
	// wsv3はダングリングポインタ
	std::wstring_view wsv3 = L"ABCDE"s;
	// std::wstring_view wsv3 = std::wstring(L"ABCDE");
	std::wcout << wsv3 << std::endl;

	return 0;
}
```

## 追加情報

C++20からは`std::span`により一般的なデータの一部を扱うことができます。文字列ビューとしてのインターフェイスが不要ならこちらも使用できます。
Jupyter上でseleniumもrequestsも同時に認証付きプロキシの設定を変更できるようにしてみた

# 利点
- OSの環境変数にProxyの設定を行う事で、Selenium,Requestsなど複数のパッケージに対して、個々にProxy設定せずに済むようになります。
- 下記実装にすることで、環境変数への設定はこのコードを実行しているブックのみで有効になるので、他への影響が少ない
- ID/パスワードをコードに固定で設定せず毎回入力するため、ソースが漏れてもセキュリティ上の影響が少ない

# ソースコード
```
import os
import getpass


class PROXY:
    # プロキシー一覧
    proxies = {
        "office":{社内で利用するプロキシーサーバーのアドレス:ポート},
        "mobile":{社外で利用するプロキシーサーバーのアドレス:ポート},
    }

    def __init__(self,prxy=None):
        self.conf(prxy=prxy)
        
    def conf(self,prxy=""):
        if prxy not in [None,"office","mobile"]:
            prxy = input("Proxy(office|mobile|none)")
        if prxy in ["office","mobile"]:
            name = input("ID:")
            password = getpass.getpass("Password")
            self.set_proxy(name,password,prxy=prxy)
        else:
            prxy = None
            self.set_proxy(prxy=prxy)

    #プロキシのID,パスワードと接続元から環境変数にProxyを設定
    def set_proxy(self,uid=None,pwd=None,prxy=None):
        #プロキシを削除
        if prxy == None:
            os.environ.pop('HTTP_PROXY', None)
            os.environ.pop('HTTPS_PROXY', None)
            print("clear Proxy")
        #プロキシを設定
        elif prxy in self.proxies.keys():
            prx = self.proxies[prxy]
            os.environ['HTTP_PROXY']="http://{}:{}@{}".format(uid,pwd,prx)
            os.environ['HTTPS_PROXY']="http://{}:{}@{}".format(uid,pwd,prx)
            print("Set {} as Proxy".format(prx))
        #プロキシを削除
        else:
            os.environ.pop('HTTP_PROXY', None)
            os.environ.pop('HTTPS_PROXY', None)
            print("clear Proxy")

    #プロキシのID,パスワードと接続元から環境変数にProxyを設定
    def check_proxy(self):
        print('HTTP_PROXY:{}'.format(os.environ.get('HTTP_PROXY', None)))
        print('HTTPS_PROXY:{}'.format(os.environ.get('HTTPS_PROXY', None)))
```

# 利用方法
下記を記載する事で、prxy=None以外はID,パスワードの入力を求められる。
正しいID,パスワードを入力する事で、当該ブックにのみ有効なプロキシ設定が環境変数に設定される。

```
#OfficeのProxy利用時
_ = PROXY(prxy="office")

#mobileのProxy利用時
_ = PROXY(prxy="mobile")

#Proxyを使わないとき
_ = PROXY(prxy=None)

```
GAS スプレッドシートが編集されたら、編集行にタイムスタンプを自動挿入したい

# やりたいこと
あるスプレッドシートにて、特定の列を更新した際に、更新日、更新時刻を記入するというルールがあったのですが、入力してくれない人がいたり、入力形式が人によってバラバラになってしまったり、といった問題がありました。
そこで、特定の列を編集した際に、更新日、更新時刻の入力を自動化したいという依頼を受けました。

# onEdit
スプレッドシートにはセルの編集時にonEditというイベントが使えるようでしたのでこちらを利用しました。

 
```JavaScript

Function onEdit(e){
  //編集した行列番号を取得する
  var row = e.range.getRow();
  var col = e.range.getColumn();

  var val = e.value;
  //1行目はヘッダー行なので、1行目以降の行の、6列目の更新を監視。
  if(col === 6 && !(row === 1) ){
  }if(col === 6 && !(row === 1) && !val){
    date = new Date();
    e.source.getActiveSheet().getRange(row,4,1,2).setValues([["",""]]);

  }else if(col === 6 && !(row === 1) ){


    date = new Date();
    e.source.getActiveSheet().getRange(row,4).setValue(date);
    e.source.getActiveSheet().getRange(row,5).setValue(Utilities.formatDate(date, "Asia/Tokyo", "HH:mm") );
  }
}

```
逆状態モナド

# 逆状態モナド

　Stateモナドは、Haskellの遅延評価とmodifyの前後で状態の型が変わらない性質のおかげで、値の伝わり方の順序を保ちつつ状態の伝わり方を逆順にした派生を作ることができる。

```Haskell
newtype Rstate s a = Rstate { runRstate :: s -> (a, s) }

instance Functor (Rstate s) where
    fmap = liftM

instance Applicative (Rstate s) where
    pure = return
    (<*>) = ap

instance Monad (Rstate s) where
    return = Rstate . (,)
    x >>= f = Rstate $ \s0 ->
        let (a, s2) = runRstate x s1
            (b, s1) = runRstate (f a) s0
         in (b, s2)

instance MonadState s (Rstate s) where
    state = Rstate
```

　まあそうなるだろうなという感じで動く。

```Haskell
>>> flip runRstate "" $ do
>>>     modify (<> "Hello")
>>>     modify (<> "World")
>>>     modify (<> "!!!!!")
((),"!!!!!WorldHello")
```

　ちょっと面白けど、そんなに奇妙な動きをしているわけではない。

## おまけ

　`RstateT`的なモナドトランスフォーマーを作ることはできない。これはモナドのバインドでは前の束縛を参照することができないからだ。

```Haskell
instance Monad m => Monad (RstateT m s) where
    x >>= f = RstateT $ \s0 -> do
        (a, s2) <- runRstateT x s1    -- ここでs1が見えない
        (b, s1) <- runRstateT (f a) s0
        return (b, s2)
```

　do構文を脱糖すれば、なぜ遅延評価をもってしても変数が見えないのかが分かる。

```Haskell
Rstate $ \s0 ->
    runRstateT x s1 >>= \(a, s2) ->    -- ここでs1が見えない
        runRstateT (f a) s0 >>= \(b, s1) ->
            return (b, s2)
```

　`Rstate`が実装できて`RstateT`が実装できないのは妙な気がするので、どうにか工夫すれば実装できそうな気がしないでもない。
TechAcademyが無料公開している「HTML・CSS入門講座」を受講する～HTML第1-1回～

# アジェンダ
* HTMLとは
* HTMLファイルを作るためのルール
* HTMLファイルを作る

## HTMLとは
HTMLとは、Webブラウザに文字を表示させるための言語。

## HTMLファイルを作るためのルール
* __HTMLで書くこと__
すなわち、意図通りに表示されていない場合、HTMLの文法に違反しているということになる。

* __ファイル名の最後に.htmlをつけること__
.htmlをつけないと、WebブラウザがHTMLファイルとして認識してくれない。

* __テキストエディタで書く__
例えば、Wordは文字色やフォントなどの情報が含まれてしまうためNG。

## HTMLファイルを作る
テキストエディタで「Hello,World!」と打ち込み、index.html と名前を付けて保存する。

```html:index.html
Hello, World!
```

このindex.htmlをWebブラウザで開くとこんな感じ。
![index.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/648214/7466deb8-6c4a-5feb-c4bd-9fb39d014f75.png)

Webブラウザに文字が表示されている。

# おわりに
今回はお決まりごとを確認する内容だった。
過不足なく、必要な情報のみを教えてくれている。さすがTechAcademy。

次回 >> [ここ](https://qiita.com/MakoMakoMakotsu/items/e9f877f50bf71efc085c)

## 参考
[1-1 HTMLとは何か？（はじめてのHTML）](https://www.youtube.com/watch?v=lqaMJDF_fy0)
PHPでcsvファイルから商品一覧ページと商品詳細ページを作る

#希望内容
自社商品の情報はデータで管理してる。
ホームページがで自社商品を紹介したい。
でもネットショップを作るほどでもない。
簡単でいいのでホームページ上で自社商品を紹介できないか？
上記希望をPHPを使って実現する方法。
#PHPコード
```index.php
<?php

//csvデータを一行ずつ読み込みhtmlとして書き出す。
//画像は、imagesフォルダに「商品ID + .jpg」で保存しているとする。 
//商品画像をクリックで、GETにてprev.phpにIDを渡す。

if (($handle = fopen("product.csv", "r")) !== FALSE) {
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {

echo <<<eof

<a href="prev.php?id={$data[0]}">
    <img src="images/{$data[0]}.jpg" />
</a>

eof;

    }
    fclose($handle);
}
?>
```

```prev.php
<?php

//商品idをGETで取得し整数化する
$product_id = intval($_GET["id"]);

//csvデータを読み込み、idが一致したら商品を書き出し終了する
//csvにはid、商品タイトル、商品説明文の順番で入っているとする
if (($handle = fopen("product.csv", "r")) !== FALSE) {
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
        
if($product_id == $data[0]){

echo <<<eof
■商品ID<br />
{$data[0]}<br /><br />

■商品タイトル<br />
{$data[1]}<br /><br />

■商品画像<br />
<img src="images/{$data[0]}.jpg"><br /><br />

■商品説明文<br />
{$data[3]}<br /><br />
eof;

break;

}
    }
    fclose($handle);
}

?>
```
データベースは使わずテキストファイルなので編集も簡単。
レンタルサーバーからのバックアップも簡単。

#疑問点
１．エラーページは作っておいた方が良い？

２．```$product_id = intval($_GET["id"]);```
これだけで無害化できている？
AWSで遊んでみたいときにかかる費用

#AWS使ってみたい
自作のポートフォリオなどでWebアプリケーションをHerokuにデプロイしたことはあるけど、
AWSは敷居が高い気がして使ったことがないという方は多いのではないでしょうか。
しかもそこそこ料金がかかるらしいし、一見すると料金がわかりにくいので躊躇してしまいますよね。

私も使ってみるまではそう思っていたのですが、
結果的にはネットワークの勉強にもなるし、汎用性の観点からも早く使ってみれば良かったなと思っています。

とはいえ、構成次第では稼働させっぱなしにすると多少費用がかかってしまいますので、
2020年6月現在の費用をお伝えします。

#WordPressが動くようにするといくらかかるのか

AWS初学者のために心底丁寧に解説されているこちらの本では、

[Amazon Web Services 基礎からのネットワーク＆サーバー構築　改訂3版](https://amzn.to/3cqAcX2)

AWSを使ってWordPressを動かすまでがハンズオン形式で書かれています。
ただし、実際に構築した場合のAWSに支払う費用までは書かれていませんでした。

この本の通りにWEBサーバー、DBサーバー、NATゲートウェイという構成でWordPressを動かし、
上記を**約１ヶ月稼働させっぱなしにした場合**、以下のような請求額になりました。（東京リージョン）

<img width="1043" alt="スクリーンショット 2020-06-01 8.07.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445558/ec0fb558-acba-afbe-d67a-19520bcdee03.png">


#１ヶ月（31日間）だと大体6,900円くらい！？

上記の画像はいろいろ弄っていたため若干の誤差があるのですが、
各製品の単価から正確に計算してみると、

- WEBサーバー(EC2 Linux t2.micro)
0.0152USD/時間 × 24時間 × 31日 = 11.309USD

- DBサーバー(EC2 Linux t2.micro)
0.0152USD/時間 × 24時間 × 31日 = 11.309USD※

※ただし、EC2は最初の12ヶ月だけ750時間/月の無料枠があるので、上記のうち1インスタンスは起動しっぱなしでも料金は発生しません。

- **NATゲートウェイ（稼働時間）　0.062USD/時間 × 24時間 × 31日 = 46.128USD**
- NATゲートウェイ（転送量）　　0.062USD/GB × 0.147GB = 0.01USD
- ストレージ(EBS) は最初の12ヶ月は30GBまで無料

となり、110円/USDとすると税込みで大体6,900円の費用がかかります。

#NATゲートウェイがそれなりにかかる

NATゲートウェイの時間単価がそれなりにするため、24時間を31日放置しているとそれだけで5,500円/月位かかります。
NATゲートウェイ自体はAmazonが運用管理をしているので、ある程度の規模であれば費用は見合うと思います。

とはいえポートフォリオ用など個人利用の範疇だと財布には優しくないかもしれません。
また、2020年5月の時点ではNATゲートウェイには停止・起動の操作がないため、
課金を止めるには削除するしかありません。


#NATゲートウェイはなくても動く
本の中ではDBサーバーにインターネットからMariaDBをインストールするためにNATゲートウェイを構築しているので、必要なソフトウェアをインストールしてしまったら、NATゲートウェイを削除しても良いかもしれません。

DBサーバー自体はWEBサーバーと接続されていれば機能するので、常時NATがなくてはいけないと言うわけではありません。
ただし、DBサーバーのアップデートなどの際は改めて構築する必要があります。

運用管理の手間は増えますが、NATゲートウェイの代わりにNATインスタンスを構築することで費用を抑えることはできます。

[公式ドキュメント AWS NAT インスタンスの設定方法](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/VPC_NAT_Instance.html)
[公式ドキュメント AWS NAT インスタンスと NAT ゲートウェイの比較]
(https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-nat-comparison.html)

#EC2のLinux t2.micro1インスタンスだけなら1,400円程度
ポートフォリオ用としてEC2だけを稼働させるということはないかもしれませんが、
本の中と同じ構成でNATゲートウェイをさっさと削除してしまった場合、
最初の12ヶ月はt2.micro1インスタンス分の費用だけなので、

(EC2 Linux t2.micro)
0.0152USD/時間 × 24時間 × 31日 = 11.309USD

税込み約1,400円/月 程度ということになります。

#AWSを触ってみたいという方におすすめの良書

ということで、各製品の単価をしっかり把握して必要なものだけを稼働させていればそれほど怖いものではないので、AWS食わず嫌いの方も是非チャレンジしてみてください。
今回参考にさせていただいた大澤 文孝さんの以下の書籍はとても丁寧に書かれていますのでおすすめです。
素敵なAWSライフを！

[【Kindle版】 Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂3版]
(https://amzn.to/2XWBFPH)
[【単行本版】 Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂3版]
(https://amzn.to/2Bnhp1V)
Julia InteractによるUI

JuliaにはInteractというUIライブラリがある。このライブラリはJupyter Notebookを含むいくつかの環境で動作する。Jupyterで使ってみた。

## Observable
InteractのベースにはObservableというオブジェクトがある。これはJavaの同名オブジェクトとほぼ同じで、アップデートされたときにアップデートを観測者に告知する役割をもつ。ただ、JavaのObservableのように能動的に登録された観測者のメソッドを呼びに行くわけではなく、コールバック関数を登録しておくフックのような受動的な役割しかないようだ。

```Julia
using Interact
o = Observable(0)
on(v -> println("updated $v"), o)
```
`on`関数で、Observableがアップデートされた際に呼び出される関数を登録する。このような関数は複数登録可能だ。Observableのアップデートは`o[] = ...`のように`[]`をつけて行う。`o`を更新すると登録したコールバック関数が呼び出される。

``` Julia
> o[] = 1
updated 1
```

## Widget
InteractのWidgetはObservableとなっている。例えばButtonであれば、クリックされた回数を内部に保持していてそれをアップデートするようになっている。

``` Julia
using Interact

btn = button("push me!")
on(times -> println("pushed $times times!"), btn)
display(btn)
```
このようにすると、ボタンを押すたびにメッセージが表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412142/a1eb0e3c-18f7-50b1-25ed-f5700f37d14c.png)

## @map マクロ
複数のObservableのいずれかが更新された場合に呼び出される関数を登録することができる。式の中に`&`をつけたものをObservableと解釈する。上の例ではObservableは1つしか出てこないけどこれを@mapマクロで書くと次の様になる。

``` Julia
using Interact

btn = button("push me!")
Interact.@map println("pushed ", &btn, "times!")
display(btn)
```

## Plots の利用
Plots ライブラリを使ってグラフをアップデートする事もできる。次のコードはObservable変数`p`に値を順次足していき、それに応じてグラフをredrawしている。値を追加する関数`update`を`@async`を使って別タスクで実行しているところがポイント。

``` Julia
using Interact
using Plots

p = Observable([])

function update()
    for i in 0:100
        p[] = append!(p[], sin(i * 2π /100))
        sleep(0.1)
    end
end

@async update()
Interact.@map plot(&p)
```

![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412142/88e5a48c-a60a-e1f8-72a1-e8443836f880.gif)

アップデートは別タスクで実行されるので、これを実行している間も、別のセルでは全く別の作業ができるところもポイント。

## WidgetとPlotsの併用

WidgetとPlotsと別タスクを併用する例として、グラフのY軸のスケールを動的に変更する例を示す。あまり意味は無いが。

``` Julia
using Interact
using Plots

p = Observable([0.0])
height = slider(1:0.1:2)

function update()
    for i in 0:100
        p[] = append!(p[], sin(i * 2π /100))
        sleep(0.2)
    end
end

@async update()
display(height)
Interact.@map plot(&p, ylims=(-&height, &height))
```
最後の行に`&`のついた変数が複数あるのがみそ。

![ezgif.com-video-to-gif (2).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412142/de16901d-802b-1953-5887-2e3555f01001.gif)


## おわりに
Intractは結構バージョンアップがはげしいようで、現在は0.10.3が最新。まだ1にもなってなくて使うのが怖いけど、Juliaはだいたいこんな感じだからなあ。。