OmniAICreator/Qiita-1.07M huggingface dataset:
Ruby on RailsをHerokuでデプロイしてみたよ。

###railsチュートリアルを初めてみてHerokuというものを知ったのでやってみる。

自分の学習の備忘録として書いていこうと思います。

##railsアプリの準備をします。
トップページ作成します。これがないと動かないらいしいです。

```ruby:app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
    protect_from_forgery with: :exception
    
    def hello
      render html: "hello, world!"
    end

    def goodbye
        render html: "goodbye,keisuke!"
    end
  end
```


次に、ルーティング設定を行います。

```ruby:config/routes.rb
Rails.application.routes.draw do
  root'application#goodbye'
end
```


さらに、gemfileを書き換えます。
sqlite3はこの中に入れましょう。

```ruby:gemfile
group :development, :test do

　gem 'sqlite3' 

end
```
追記分はPostgreSQLのための設定
Herokuはsqlite3に対応してないらしい

```ruby:gemfile
group :production do

  gem 'pg'

end
```

gemfileを書き換えたらrbundle installを行います。--without productionオプションはgroup :produciton do~end内のgemは、インストール対象外となるそうです。

`bundle install --without production`

本番環境でPostgreSQLを使用する設定

```yml:config/database.yml
production:
  <<: *default
  adapter: postgresql
  encoding: unicode
  pool: 5
```

画像を表示するなら

```ruby:config/environments/production.rb
config.assets.compile = true
```

##gitの準備をします。
作成したrailsアプリのデイレクトリに移動して紐づけます。
`git init`

デイレクトリ内のファイルを全てaddしておく
`git add --all`

commitしておく
`git commit -m "commit!!"`

いつものgitの流れですね。

##herokuの登録とインストール
登録先
https://signup.heroku.com/login
登録が終わったらインストーラーをダウンロードしましょう。

インストールができたら、確認してみましょう。

`heroku -v`
で

```
heroku/7.39.3 darwin-x64 node-v12.16.2
```

とでれば成功です。

Herokuにログインします。パスワードを聞かれたら登録した時のパスワードを入力しましょう。
`heroku login`

そして、railsアプリのディレクトリ内で

`heroku create アプリケーション名`

で紐付けます。
アプリケーション名は小文字の英数で入力しましょう。

では、デプロイの準備が整いました。

`git push heroku master`

で表示されたURLにアクセスすると、下の画像のような画面が表示されます。<img width="1070" alt="スクリーンショット 2020-04-21 23.54.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598005/1150d94e-02a4-6e2b-ed79-e8fd3bb3ed94.png">

自分で書いたページが表示されました。これで、ネット上に自分のサイトやアプリを公開することができます。
夢が広がりますね！！

##更新のデプロイ方法
プロジェクトを作成していき、変更する時などは、

`git add --all`
`git commit -m "v2"`
`git push heroku master`

で更新することができます。

ログの確認は、
`heroku logs`

過去のデプロイ確認は、
`heroku releases`

過去のバージョンに戻したい場合は、
`heroku rollback v~`

DBマイグレーションは、
`heroku run rails db:migrate`

です。
以上が、Herokuとrailsのデプロイ方法でした。
シリアル通信で漏れなくコマンドを実行するTeratermマクロ

シリアル通信で `sendln` などすると途中で送信が漏れたり、入力がテレコ(`abc` のはずが `acb`)になったりするので、マクロなのに目が離せなくてつらい。なので 1 文字入力するごとに正しくエコーバックすることを確認するサブルーチンを使う。

```:例
wait '$'
COMMAND='date'
call exec

wait '$'
COMMAND='uname -a'
call exec

wait '$'
COMMAND='id -a'
call exec

end


:exec
    flushrecv
    strlen COMMAND
    endloop = result
    for i 1 endloop
        strcopy COMMAND i 1 ch
        send ch
        ; wait ch 動かないらしい
        mpause 1000
    next
    sendln
return
```
プログラミングでスロットを勝てるようにしたい

![building_pachinko.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624779/54885223-fe22-5ccc-0139-465d10120983.png)

<h1>初回の記事なので軽く自己紹介</h1>

神奈川で働くパチンコ産業に携わるしがないサラリーマン
約5年前にこの関東平野に引っ越してきた。

こっちに来てからは天井狙いから設定狙いにシフト。
**年単位で見ると月平均10万前後まで勝てるようにはなった。**
時給にすると1000円ちょっと（悲しい)

スロットでの稼ぎ方を自分なりに色々と試してみた結果や
自分なりの知識のアウトプットをここでできればと思っている。

データ収集方法を考えてみてプログラミングでなんとかしたいと思っており、
ruby.pythonあたりを勉強中。

いつかはスロットで勝つために便利なツールを開発したい。

これからスクレイピングやデータ分析などをしてスロットでもっと稼げるようになりたい。
同志の方いれば是非フォローしてください.

次は稼ぎ方別で見るスロットの稼ぎ方でも書こうかな。
twitterもフォローしてね。
MACからwin10 home editionへリモート接続

MACでwin10 home editionへリモート接続できたので備忘録

####Mac側
リモートアプリをインストールする必要がある。

**Remote Desktop**

* appstoreからインストールします。

https://apps.apple.com/jp/app/microsoft-remote-desktop-10/id1295203466?mt=12

* 設定手順は以下でわかりやすく記載してくれています。

https://pc-karuma.net/mac-app-microsoft-remote-desktop/

####Windows10 Edition:HOME
Proはリモートデスクトップ設定が可能ですが、HOMEはそのままでは出来ない。
その為、同様に専用のソフトをインストールする必要がある。


* 手順は以下でわかりやすく記載してくれています。

https://temcee.hatenablog.com/entry/2016/11/05/005641
※2020/04/21時点では[RDP Wrapper Library v1.6.2](https://github.com/stascorp/rdpwrap/releases)が最新

ただ、windowsアップデートなどでバージョンが変わるとリモート出来なくなる。
上記設定をしてもリモートできなかった。

その場合はwinsows側（リモートされる側）でファイルの修正が必要になる
その対処方が以下に記載されている
https://tanisukestr.hatenablog.com/entry/2019/04/14/225533

私の場合、上記でiniを修正しているが、versionが違ったのでうまくいかなかった。

確認したら＜Ver 10.0.18362.267＞だったのでrdpwrap.iniを下記の設定値へ修正したらいけた。
https://github.com/asmtron/rdpwrap/blob/master/res/rdpwrap.ini
Google翻訳のchrome拡張で翻訳スピードを爆上げしよう！

## はじめに

開発してて何かにハマったりした時やまだ新しい技術を調べたりする時に、英語のサイトを見ることはよくあると思います。
英語に強い人なら問題なく読んでいくことが出来ると思いますが、僕はとても読むのが苦手です。ただ、頑張って読めるようになろうと勉強してた時期もあったのですが、開発してる時間より英語調べてる時間のほうが長くなり全く生産性が出なくなってしまったのでやめました。:innocent:

そこでGoogle翻訳を使い始めました。最初はわからない文章が出てくるたびに新しいタブでGoogle翻訳開いて文字入れて翻訳ボタン押して、のようなことをしていました。最初は「Google翻訳便利〜！」って感じてましたが、だんだん毎回タブ開いたりすることが億劫になってきました。
そのページをまるごと翻訳する機能も試してみたのですが、ぶっちゃけ時間かかりますよね。あまりに意味わからない日本語が出力されることもありますし。

わからないところだけをシームレスに翻訳出来れば最高です。そういうツールが無いか探してみたら、ありました！

## Google翻訳のchrome拡張機能がとても便利！

早速結論から。 [Google翻訳のchrome拡張機能](https://chrome.google.com/webstore/detail/google-translate/aapbdbdomjkkjkaonfhkkikfgjllcleb?hl=ja) を入れましょう。
これを入れると↓のようなアイコンが出てきて、クリックすると翻訳のタブが出てきます。

[![Image from Gyazo](https://i.gyazo.com/795441dbd2ba2ce340fc76af4d3e788a.png)](https://gyazo.com/795441dbd2ba2ce340fc76af4d3e788a)

英文入れて「翻訳」ボタンをクリックで翻訳できます。

これだけでも割と便利ですが、英文をカーソル指定すると翻訳アイコンが出てきてクリックすると翻訳できちゃいます。良いですね。

[![Image from Gyazo](https://i.gyazo.com/a0fd8cfc630cb80f363c5993d5bd53dd.png)](https://gyazo.com/a0fd8cfc630cb80f363c5993d5bd53dd)

カーソル指定するだけで自動で翻訳してくれるように設定を変更することも出来ます。

## ショートカットと組み合わせるともっと快適に！！

chrome拡張を入れただけでも割と快適になるのですが、更に「拡張機能のショートカット」を設定することでもっと快適に出来るんです！
Macのchromeだと、メニューバーの「ウィンドウ」→「拡張機能」から拡張機能の一覧ページに飛べます。

![スクリーンショット_2020-04-21_23_37_33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33557/60c565b7-40a0-6938-72c6-6e35a4b6db1b.png)

そこから、左上のハンバーガーメニューから「キーボードショートカット」を選択しましょう。

![スクリーンショット_2020-04-21_23_41_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33557/a5233fa7-d38b-cfca-a452-36fa48796592.png)

キーボードショートカットを設定できる画面に飛んだら、ショートカットを設定してあげましょう。ちなみに僕は「Cmd + Shift + g」で拡張機能を起動するようにしています。

![スクリーンショット 2020-04-21 23.45.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33557/12c3b5ff-0c1b-d89d-7660-2c8f087e4927.png)

これで、英文カーソル指定→ショートカットキーを押すだけで英文を翻訳できるようになりました！
その動作が以下になります。

[![Image from Gyazo](https://i.gyazo.com/7612b799b3240a9bad93896d12c645fe.gif)](https://gyazo.com/7612b799b3240a9bad93896d12c645fe)

求めていたわからないところだけをシームレスに翻訳する環境が手に入りました！

## おわりに

以上、Google翻訳の拡張機能を使って翻訳を楽にする方法でした。英語をサクサク翻訳して良い開発ライフを！
Column not found: 1054 Unknown column '_token' in 'field list'，Column not found: 1054 Unknown column '_method' in 'field list'

Column not found: 1054 Unknown column '_token' in 'field list',
Column not found: 1054 Unknown column '_method' in 'field list'の解決方法


####Column not found: 1054 Unknown column '_token' in 'field list
#####原因箇所
```
->update($request->all());
```
#####解決策
```
->update($request->except(['_token']));
```

####Column not found: 1054 Unknown column '_method' in 'field list'
上記の解決策を試したところ、私の場合PUTメソッドを使用しており、Laravelが自動的に非表示の_methodフィールドを追加していたため、新たなエラーが起きたようです。
#####原因箇所
```
->update($request->except(['_token']));
```
#####解決策
```
->update($request->except(['_token', '_method']));
```
動かして覚えるPythonコード一覧

##本記事について
プログラミングから長く離れていたので、練習・復讐を兼ねてPythonの超初心者用コードを実際に動かしてみました。

プログラムを実際に動かした経験を備忘録を兼ねて残しています。
誰かのお役に立てれば幸いです。

##変数宣言
Pythonでは変数を事前に宣言する必要はありませんが、変数宣言は可能です。
必要性は薄いですが、可読性を高める必要がある場合などに利用します。
※実行結果は type()で確認してみてください。

```python: 
# integer 型
num: int = 1

# string型
text: str = '1'

# boolean型
isEnabled: bool = True

```

###変数名に使える文字
- 英字（小文字）
- 英字（大文字）
- 数字
- アンダースコア（ _ ）

###変数名のルール
- 数字から始まるものは使えない


##型の確認方法
pythonは、変数宣言（型指定）の必要がありません。
何の型が設定されているか確認する場合は、オブジェクトの型を取得・確認するtype()関数を使用します。

```python: 

num: int = 1
print(num , type(num))
#1 <class 'int'>

text: str = '1'
print(text, type(text))
#1 <class 'str'>

isEnabled: bool = True
print(isEnabled , type(isEnabled))
#True <class 'bool'>

```
Javaソースコードの基本構造

# Javaソースコードの基本構造

```java
public class Main {
// 以下クラスブロック
  public static void main(String[] args) {
  // 以下メソッドブロック
    System.out.println("Qiitaを更新します");
    System.out.println("タイトル：Javaソースコードの基本構造");
    System.out.println("お願い:間違っていたらコメントお願いします");
  }
}
```

クラスブロックと外側は、毎回ほとんど同じ。
メソッドブロックに、処理命令を記載する。
[C++] しょうもないバグ　記録

##はじめに
AtCoderのためにC++を学習し始めた初心者。
些細なミスに取り乱され、バグを探すこと気づけば一時間。

二度と同じミスをしないために、記録
（テキストエディタはVScode(WindowsPowerShell))


###if文（等価演算子）

```cpp
if(n=0){  }
else{  }
```

正解`n==0`　
ビルドできちゃうんだよね。`if(n=0)`==`if(0)`と判定されます。
（追記：g++コンパイル時に`g++ -Wall`のようにオプション付けたら警告してくれました。）

###vectorの標準入力

```cpp
int n; cin >> n;           //vectorの要素数
vector<int> a;           
for(int i=0;i<n;i++){      
    cin >> a[i];           //vectorの標準入力
}
```

正解`vector<int> a(n)` 
`cin >> a[i]`　この形は、vectorの定義時に要素数を定めないといけません。
要素数を指定しない場合は、`a.push_back()`を使います。

###for文 

```cpp
int a = 3; int b = 7 
for(int i = a; a <= b; i++){  }  // i=aからbまで
```

正解`for(int i = a; i <= b; i++){  }`
ループし続けてしまいました.....😢

###出力表示、桁数

```cpp
double a = 23456789.123

cout << a;

// 出力：2.34568e+007　
```

出力結果が指数表記になっています。このままでAtcoderに提出すると、解釈してくれません。
そこで、以下のようにすることで、小数点以下の桁数を指定しつつ実数表記できます。

```cpp
// printfを使った方法
printf(%.2,a);
// 出力：　23456789.12

// coutを使った方法
cout << fixed << setprecision(2) << a;
// 出力：　23456789.12
```

#### 最後に
都度更新。
PythonとSymPyで連立常微分方程式を解く。

ここではPythonにsympyをインストールして連立常微分方程式を解いてみたいと思います。

## sympyのサイト
https://docs.sympy.org/latest/index.html

### ウォーミングアップ

まずはsympyを用いた基本的な関数の微分の例を書いておきます。

```python:
import sympy as sym
x = sym.Symbol('x')
h = x**3 + 3*x + 1
h.diff(x,1)
```

## 連立一次常微分方程式

ではおもむろに連立一次常微分方程式を解いてみましょう。

```python:
x = sym.Symbol('x')
f = sym.Function('f')
g = sym.Function('g')
h = sym.Function('h')
eq1 = sym.Eq(f(x).diff(x,1),g(x)+h(x))
eq2 = sym.Eq(g(x).diff(x,1),h(x)+f(x))
eq3 = sym.Eq(h(x).diff(x,1),f(x)+g(x))
sym.dsolve([eq1, eq2, eq3])
```

## 偏微分方程式には対応してない？

調子に乗って偏微分方程式を解いてみましょう。

偏微分の計算自体は可能です。

```python:
x = sym.Symbol('x')
y = sym.Symbol('y')
u = x**2 - y**2
u.diff(x,1)
```

しかし、以下の様な計算をさせようとしても上手く答えが出てきません。

```python:
x = sym.Symbol('x')
y = sym.Symbol('y')
u = x**2 - y**2
v = sym.Function('v')
eq1 = sym.Eq(u.diff(x,1), v(x,y).diff(y,1))
eq2 = sym.Eq(u.diff(y,1), -v(x,y).diff(x,1) )
sym.dsolve([eq1, eq2])
```

う～む…。大学２年生相当くらいまでは対応していて、３年生相当以上になるとまだちょっと対応できてないのですかね。(;^_^A
【Git】addする前/した後にdiffで差分をみる

## `add`する前に、差分をみる方法

```
% git diff <filename>
```

## `add`した後に、差分をみる方法

```
% git add .
% git diff --cached <filename>
```

## `add`した後に、addを取り消す方法
```
% git add .
% git restore --staged <filename>
```

## `add`する前に、変更前まで戻す方法
```
% git restore <filename>
```

## 上記のコマンドを使った操作例
`<filename>`の内容を変更する
↓
`% git diff <filename>`(commit済ファイルとの差分をみる)
↓
`% git add <filename>`(ファイルをステージングエリアに追加)
↓
`% git diff --cached <filename>`(commit済ファイルとの差分をみる)
↓
`% git restore --staged <filename>`(addを取り消す)
↓
`% git restore <filename>`(ファイルへの変更を取り消す)
↓
`<filename>`の内容が変更前の状態にもどる

## 最後に
ここで紹介しているものは、**`commit`済ファイルとの差分をみる方法**です。
`diff`コマンドについてのより詳しい情報は [忘れやすい人のための git diff チートシート](https://qiita.com/shibukk/items/8c9362a5bd399b9c56be) を参考にしてください。
macOS Catalina から Proxy 経由で SSH 接続する

## 問題点

下記の記事を参考に Proxy 経由で SSH 接続しようとしたが、上手くいかなかった。

[22番ポートが使えなくても、SSHでGitしたい！ - Qiita](https://qiita.com/306_san/items/28c36e52346f315d0860)

macOS に標準で組み込まれている nc コマンドが期待通り動いていないようだ。

```ssh:.ssh/config
ProxyCommand=nc -X connect -x {server}:{port} %h %p
```

```ssh
nc: Proxy error: "HTTP/1.1 200 Connection established" 
ssh_exchange_identification: Connection closed by remote host
```

## 解決方法

下記の記事を参考にして、 nmap の ncat を使用するよう変更した所、上手くいった。

[Mac OSXでHTTP Proxy経由でSSH - Qiita](https://qiita.com/yuyhiraka/items/30766c69fb605fc5f182)

```ssh:.ssh/config
ProxyCommand=ncat --proxy-type http --proxy {server}:{port} %h %p
```
[LiveData] 更新されたときだけ値を受けとる

二通りの方法を示します。

### 1. LiveData を BroadcastChannel に変換する

いきなりテストです。

```kotlin
class MyTest {
    private val dispatcher = TestCoroutineDispatcher()

    @[Rule JvmField]
    val rule = InstantTaskExecutorRule()

    @Before
    fun before() {
        Dispatchers.setMain(dispatcher)
    }

    @After
    fun after() {
        Dispatchers.resetMain()
        dispatcher.cleanupTestCoroutines()
    }

    @Test
    fun test() = dispatcher.runBlockingTest {
        // ソースとなる LiveData
        val source = object : MutableLiveData<Int>(0) {
            override fun onActive() = println("onActive")
            override fun onInactive() = println("onInactive")
        }

        // BroadcastChannel に変換
        val broadcastChannel = source.asFlow().broadcastIn(this)

        // Flow に変換 (都度 broadcastChannel.openSubscription() しても良い)
        val flow = broadcastChannel.asFlow()

        val job1 = launch { flow.collect { println("coroutine1: $it") } }

        source.value = 1

        job1.cancel()

        source.value = 2

        val job2 = launch { flow.collect { println("coroutine2: $it") } }

        source.value = 3

        job2.cancel()

        broadcastChannel.cancel()
    }
}
```

実行結果は以下です。

```
onActive
coroutine1: 0
coroutine1: 1
coroutine2: 3
onInactive
```

`coroutine1` では初期値 `0` および `1` を受信していますが、`coroutine2` では `3` だけを受信しており、直前の値 `2` を受信していないことがわかります。

利点

- 特別な仕組みを作りこむ必要がない

欠点

- おまじないっぽい？
- 多くの関数が `@ExperimentalCoroutinesApi` だったり `@FlowPreview` だったりする


### 2. LiveData.getVersion() を使う

`androidx.lifecycle` パッケージ配下に以下の関数を用意します。

```kotlin
package androidx.lifecycle

internal fun LiveData<*>.version() = version
```

次に、任意のパッケージ配下に以下の関数を用意します。


```kotlin
@MainThread
fun <T> LiveData<T>.observeChangesForever(action: (T) -> Unit): Observer<T> =
    object : Observer<T> {
        private val version = version()
        override fun onChanged(t: T) {
            if (version() > version) action(t)
        }
    }.also { observeForever(it) }
```

> 省略していますが、LifecycleOwner を受け取る関数も同じように作ることができます。

テストは以下です。

```kotlin
class MyTest {
    @[Rule JvmField]
    val instantTaskExecutorRule: InstantTaskExecutorRule = InstantTaskExecutorRule()

    @Test
    fun test() {
        // ソースとなる LiveData
        val source = object : MutableLiveData<Int>(0) {
            override fun onActive() = println("onActive")
            override fun onInactive() = println("onInactive")
        }

        val observer1 = source.observeChangesForever { println("observer1: $it") }

        source.value = 1

        source.removeObserver(observer1)

        source.value = 2

        val observer2 = source.observeChangesForever { println("observer2: $it") }

        source.value = 3

        source.removeObserver(observer2)
    }
}
```

実行結果は以下です。

```
onActive
observer1: 1
onInactive
onActive
observer2: 3
onInactive
```

`observer1`・`observer2` 共に直前の値 (`0` および `2`) を受信していないことがわかります。

利点

- わかりやすい (かも)

欠点

- 作りこみが必要
- LiveData.getValue() はパッケージプライベートなので、今後動かなくなるかも

二通りの方法を示しましたが両者は挙動が異なるので、使い方には注意が必要です。

以上です。
[SavedStateHandle] やっぱりDaggerとうまく付き合う

以前 SavedStateHandle を DI する方法について[記事を書きました](https://qiita.com/Tsuyoshi_Murakami/items/12678bc77d9a9f2e5813)が、今は正直以下の方法でも良いのではないかと思っています。

```kotlin
class MyViewModel(handle: SavedStateHandle) : ViewModel() {
    @Inject
    lateinit var myRepository: MyRepository

    val myData: LiveData<MyData> = liveData {
        emitSource(myRepository.getMyData())
    }
}
```

```kotlin
class MyFragment : Fragment() {
    private val viewModel by viewModels<MyViewModel>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        (requireActivity().applicationContext as App)
            .component
            .inject(viewModel)
    }
}
```

SavedStateHandle はデフォルトの ViewModelFactory におまかせして、それ以外のコンポーネントをフィールドインジェクションでセットする方法です。

テストはしていません。
以上です。
Scalaの名前渡しについてきちんと説明する

# Scalaの名前渡しについてきちんと説明する。
先日、Scalaの[名前渡しについての記事](https://qiita.com/gal1996/items/c3e41ec7c0025afb307b)を書きました。
この記事の内容も間違っている、というわけではないのですが、よりきちんと理解しないと説明ができないパターンに出会ったので、今回はそれについて書こうと思います。

# 今回扱うパターン
 今回説明したいパターンはこんなパターンです。

```Scala
  def mapForTuple[A, B](tuple: (A, A), f: => A => B): (B, B) = {
      val _f: A => B = f
      val (x, y) = tuple
      (_f(x), _f(y))
```

関数の実装としては、`Tuple2`を受け取って、それぞれの値に関数fを適用して、適用後の値の`Tuple2`を返す、というような場合です。
ここで、fに渡す関数が以下のような場合の時に今までの理解では説明できない状況になりました。
それがこのような場合の時です。(テストコードで書いてます。）

```Scala
TimeLimits.failAfter(60 millis) {
      mapTuple[String, Int](("aa", "bbb"), { Thread.sleep(50); _.length }) shouldBe ((2, 3))
}
```
このテストは上の関数の実装だと60ms以内に実行が終わります。

今までのような理解で

```Scala
val _f: A => B = f // f = { Thread.sleep(50); _.length }
```

だと理解すると、

```Scala
(_f(x), _f(y))
```

の部分で並列で処理されない限りは`Thred.sleep(50)`が２回実行されて60ms以内には実行が終了しなさそうに見えます。
ですが、実際はこのテストは通ります。
これは、名前渡しがどのようにコンパイルされているかがわかると解決できます。

# 名前渡しの引数がコンパイルされるとどうなるのか
結論から言うと、名前渡しの引数はコンパイルされると`Function0`になっています。つまり引数を取らない関数になっていると言うことです。
今回の場合はfがFunction0になっているので、fは以下のようになっています。

```Scala
() => (A => B)
```
fは`A型を受け取ってB形を返す`処理をする関数を返す関数です。
ここで、名前渡しの挙動に戻ります。名前渡しの場合その関数は使用される場合に評価されます。と言うことはfが評価されるのは、

```Scala
val _f: A => B = f // f = { Thread.sleep(50); _.length }
```
このタイミングです。なんとなく分かってきたでしょうか。fは`A型を受け取ってB形を返す`関数なのです。つまり`_.length`が`A型を受け取ってB形を返す`関数になっています。fの値は`_.length`です。コンパイラがこの部分を`Function0`として入れています。なので、このタイミングでは`Thread.sleep(50)`が実行されますが、この時１回だけです。のちの`_f`の呼び出しでは実行されません。
こう書いた方がわかりやすいかもしれないです。

```Scala
val _f: A => B = { Thread.sleep(50); _.length }
```
こうみると`_f`に最終的に入る値って、`_.length`ですよね。なので`_f`の中には`Thread.sleep(50); _.length`ではなくて、`_.length`だけがFuncion0として入っていると言うことでした。

#最後に
　この記事を書いていて、賢い人なら

```Scala
val _f: A => B = f // f = { Thread.sleep(50); _.length }
```
をみた時点で、`_f`は `_.length`だなってなるかもなって思ったのですが、僕は`{ Thread.sleep(50); _.length }`全部が`_f`の中に入っていると勘違いしてしまったので、なんであのテストが通るんだろうと、不思議になってしまいました。コンパイルした結果`Function0`になっていると言うところから、理解できたので、まとめてみました。
CentOS7で指定時間になったらパケットキャプチャーを実行する

とあるお客様から「指定時間になったら定期的にパケットを取得して欲しい」と言われ、
急遽キャプチャ用PCとしてCentOS7を構築したのですが（ググりながら）、
そのときのものを備忘録として残します。


CentOS7のバージョンは以下

```
[smatsu@smatsu ~]$ cat /etc/redhat-release
CentOS Linux release 7.7.1908 (Core)
```

　
#やりたいこと
指定した時間にパケットキャプチャーを実行したい。

#手段
Wiresharkを実行するシェルスクリプトを作成して、スケジュール機能はCentoS7標準のcronを使用する。




#CentOSインストール
詳細は省略。
環境に合わせて仮想マシンを設定。
サウンドカード、フロッピー、プリンターなどは使わないのでこの時点で削除。
今回はGNOMEでインストールしています。


#Wiresharkをインストール
GUIなのでgnomeをつける。

```
$ sudo yum install -y wireshark-gnome
```
　
入りました。

```
[smatsu@smatsu ~]$ wireshark -v
wireshark 1.10.14 (Git Rev Unknown from unknown)
```
　
GUIではこちらから確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224022/db329a9b-ff34-8817-7fff-7f384d0c5f9d.png)

このままだと一般ユーザでは権限の問題でインターフェースが表示されませんので権限を与えます。

```
$ sudo groupadd wireshark
$ sudo usermod -aG wireshark [user]
```
ここで再起動。
　
　
インターフェースが表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224022/e02640a6-8cad-f05b-f188-f4313c3dac18.png)

　
GUIはあくまで確認用で、ここからはCLIで設定していきます。


#実行ファイルを作成
まずは作業用フォルダを作成。

```
$ mkdir pcap
$ cd pcap
```
　
次に実行ファイルを作成。

```pcap.sh
#!/bin/bash

/usr/sbin/tshark -i ens33 -w /home/smatsu/pcap/`date +\%Y\%m\%d`/`date +\%Y\%m\%d_\%H\%M`.pcapng -a duration:600
```
・tshark = コマンド版Wireshark
　・gnomeをインストールすれば入っています
・ens33 = キャプチャーしたいインターフェース名
・ファイル名は日付フォルダ配下に"(日付).pcapng"で格納
・キャプチャ時間は600秒
　
実行権限を与えておく。

```
chmod +x pcap.sh
```


#スケジューリング設定
実行ファイルをスケジューリングするためcronを設定していく。
cronの状態を確認。

```
[smatsu@smatsu ~]$ systemctl status crond
● crond.service - Command Scheduler
   Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2020-04-21 22:34:28 JST; 8min ago
```
　
※ここで有効化されてない場合は、有効化する。

```
$ systemctl start crond
```
　

crontabで実行するコマンドを編集。

```
$ crontab -e
0 6 * * * /usr/bin/mkdir /home/smatsu/pcap/`date +\%Y\%m\%d`   # 毎朝6時に日付のフォルダを作成
0 7 * * * /home/smatsu/pcap/pcap.sh                            # 毎朝7時にキャプチャーファイルを実行 
```
※ :wqで保存

　
cronの内容を確認。

```
[smatsu@smatsu pcap]$ crontab -l
0 6 * * * /usr/bin/mkdir /home/smatsu/pcap/`date +\%Y\%m\%d`
0 7 * * * /home/smatsu/pcap/pcap.sh
```


　
これで毎朝日付フォルダ配下にパケットキャプチャを保存できます。
【Rails Docker Git】よく使うコマンド一覧

# 【Rails Docker Git】よく使うコマンド一覧

## Dockerでサーバー立ち上げ
```:terminal
> docker-compose up
```

## Dockerでサーバーダウン
```:terminal
> docker-compose down
```

## DockerでDB確認
```:terminal
> docker-compose ps
```

## rails db:create
```:terminal
> docker-compose exec イメージ名 ./bin/rails db:create
```

## railsタスク一覧（コマンド一覧）
```:terminal
> docker-compose exec web ./bin/rails -T
```

## gitのカレントブランチを確認
```:terminal
> git branch
```

## gitのブランチを新規作成してテェックアウト
```:terminal
> git checkout -b ブランチ名
```

## gitのステージングされテイルファイルのキャシュをみる
```:terminal
> git diff -cashed
```

## gitのブランチを削除する
```:terminal
> git branch -d 削除したいブランチ名
```


## gitのブランチをmergeする
```:terminal
> git merge マージしたいブランチ名
```

## リモートブランチを取得して、継続して開発したいとき
```:terminal
> git fetch origin リモートブランチ名
> git checkout -b リモートブランチ名 origin/リモートブランチ名
```
View を支えるトリガーアクション

## はじめに

オレオレ解釈の覚え書き　その５

トリガーアクションについてです。
※今回も Expression Blend に付属する Trigger, Action について触れていきます。

## 本文

トリガーは動作のきっかけを通知する機構で、トリガーが何かを感知したときに行われる処理がアクションです。これらはセットで使用されるため、まとめてトリガーアクションと呼ばれています。
トリガーにはいくつか種類があります。ここではコントロールのイベント発生を感知する EventTrigger を使ってみます。以下の例では、メッセージボックスを表示するアクションを用意し、ウィンドウがロードされたときに起動するように紐づけています。

```cs:TriggerAction
namespace TestApp.Views.Behaviors
{
    public class MessageAction : TriggerAction<DependencyObject>
    {
        protected override void Invoke(object parameter)
        {
            var owner = this.AssociatedObject as Window ?? Window.GetWindow(this.AssociatedObject);
            MessageBox.Show(owner, "メッセージ", "タイトル", MessageBoxButton.OK, MessageBoxImage.Information);
        }
    }
}
```

```xml:View
<Window x:Class="TestApp.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
        xmlns:behaviors="clr-namespace:TestApp.Views.Behaviors">

    <!-- トリガーとアクションを設定できる -->
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <behaviors:MessageAction/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Window>
```

この例のような動作はビヘイビアでも実現できるでしょう。両者の違いは、同じ処理をさせるか、同じふるまいをさせるかにあります。アクションは処理だけが切り出されており、特定のイベントに依存しません。イベントの感知はトリガーに任せています。一方でビヘイビアは処理のきっかけとなるイベントまで丸ごと部品化されています。

## おわりに

今回はトリガーアクションについてでした。
数回に分けてまとめてきた View を支える要素ですが、少し掘り下げただけでも、この構成の奥深さが垣間見えてきます。これらの仕組みを活用することで、処理どうしの癒着が減り、再利用しやすいプログラムの構築に近づくはずです。

View は一区切りにして、次回は ViewModel の相互作用処理についてまとめてみます。今回のテーマであるトリガーアクションにも関係がある仕組みになります。
Oracle DataBaseからストアドプロシージャを一括でファイル出力する方法


## はじめに
とあるシステムを引き継いだのですがストアドプロシージャやパッケージがOracle内にしか登録されておらず、テーブルの利用状況などを確認するのに不便だったので、一括でファイル出力する処理を作ってみました。

WindowsコマンドとSQLしか利用していないのでおそらくどの環境でもできると思います。

(資料がきちんとあれば問題ないだろというツッコミはスルーします)

## バッチファイル、SQLの作成

* 取得するSQLを作成する。SQLファイルとして保存する。 

```SQL:oracle_source_output.sql
SET pagesize 0
SET linesize 10000
SET feedback off
SET trimspool on
SET termout off

VARIABLE sourceType VARCHAR2(12)
VARIABLE sourceName VARCHAR2(30)

EXECUTE :sourceType := '&2'
EXECUTE :sourceName := '&3'

SPOOL &1

SELECT
    TEXT
FROM
    USER_SOURCE
WHERE
    TYPE = :sourceType
AND NAME = :sourceName
ORDER BY
    LINE
/
SPOOL OFF
/
EXIT
/
```

* SQLを実行するバッチを作成する。バッチファイルとして作成する。

``` :toracle_source_output.bat
@echo off
set outputMainFolder=C:\temp\
set sourceType=%1
set sourceName=%2
set extension=.SQL

rem '、空白を削除
set subFolder=%sourceType:"=%
set subFolder=%subFolder: =%

set outputFolder=%outputMainFolder%%subFolder%\

If not exist %outputFolder% mkdir %outputFolder%

set fileOutput=%outputFolder%%sourceName%%extension%

rem CSV出力処理
rem 引数1:ファイル出力先、引数2:タイプ、引数3:名称
sqlplus -s ID/Password@スキーマ名 @C:\temp\batch\oracle_source_output.sql %fileOutput% %sourceType% %sourceName%
```

* 作成したファイルを適当な位置に保存する。ここではC:\temp\batchに保存する。

## 取得用コマンドの作成
* ストアドプロシージャのソースを取得したいDBに接続する。

* user_sourceから取得したいタイプ、名前を取得する。この時、distinctを設定し、重複しないようにする。

``` SQL:コマンド取得用SQL 
SELECT DISTINCT 
    'C:\temp\batch\oracle_source_output.bat' || ' "' || type || '" ' || name AS command 
FROM 
    user_source 
order by 
    command
```

## コマンド実行

取得された結果をコマンドプロンプトで実行する。取得した結果がファイルとして作成される。


## 備考

- 作成されたファイルはCREATE文が付随していません。そのため、ストアドプロシージャを作成する際は適時CREATE文を入力する必要があります。 　
- PACKAGE BODYなど空白を含むものについては格納するフォルダは空白を削除するようにしています。
- 実行したことによりDBへの影響については自己責任でお願いします。あらかじめご了承ください。
ポータルサイト（？）創作記：７日目

さて、昨日はMVCモデル（モデル、ビュー、コントローラー）について詳述した。

今日は、これから則っていくテキストを紹介しようと思う。
これだ。
<img width="692" alt="スクリーンショット 2020-04-21 22.47.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576912/53d06ebb-340d-1c1e-4f48-11cd1fdd04d9.png">

特に惹かれたのはココ。
<img width="493" alt="スクリーンショット 2020-04-21 22.49.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576912/a9fe7f73-e229-1b1c-7a56-b2c1dcf9a38e.png">
おいおい、そんなにアプリ創れちゃうのかよっ！

個人的には、こういう基本的なアプリを作りながら学びを深め、APIの利用やらの応用に挑戦していきたい所存である。

と、いうことで、明日から、このテキストでマイペースにアプリをつくってイクゥ。
Gitアカウントを個人用と仕事用で使い分ける

## 個人用と仕事用でGitアカウントを使い分けたい
間違って個人のアカウントで社内のリポジトリにコミット・プッシュしてしまった・・・なんてことにならないためにGitアカウントを設定する。


## メインのGitアカウントに設定
全てのリポジトリにGitアカウントが設定される。

```
$ git config --global user.name "ユーザー名"
$ git config --global user.email "メールアドレス"
```

~/.gitconfigへGitアカウントが設定される。

## プロジェクト毎にGitアカウントを設定

リポジトリ毎にGitアカウントを設定する。
メインのGitアカウントを設定していても、こちらの設定が優先される。

```
$ git config --local user.name "ユーザー名"
$ git config --local user.email "メールアドレス"

```

プロジェクトの./.git/configに設定する。
【AWS】EC2のログをCloudWatchに送る

##やりたいこと
EC2インスタンス内のログをAWSで管理したい。

##ログをAWSで管理すると嬉しいこと
+ Zabbixなどの監視用ミドルを使わずにログを監視できる
+ ログをリアルタイムにLambdaで処理できる
+ S3に転送できたり、Kinesisと連携できたりする

用途は様々あるので、その手始めとしてCloudWatch Logsを使用してEC2内のログをCloudWatchに送る。
<img width="500" alt="Qiita logo" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328551/31b84676-087b-0cf5-609d-c80c64443122.png"> 

##1. CloudWatch書き込み用のポリシーを作成してEC2のロールに紐づける
「IMA」→「ポリシー」→「ポリシーの作成」
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328551/6695da25-9046-9636-481b-09c6496e4b3b.png)

「JSON」のタブを選択し、ポリシーを追加する。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328551/15360415-e6c9-ebdd-a101-ea1f08a1c068.png)


```
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents",
        "logs:DescribeLogStreams"
    ],
      "Resource": [
        "*"
    ]
  }
 ]
}
```
参考：https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/QuickStartEC2Instance.html

ポリシー名を記載して「ポリシーの作成」
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328551/d57ca5b5-8064-2f6c-636e-7e4e59b8aa4d.png)

作成したポリシーをEC2インスタンスのロールに紐づける。

## 2. EC2にCloudWatchLogsエージェントをインストールする。
※EC2のイメージはAmazonLinux2を使用しています

```:CloudWatchLogsエージェントのインストール
$ sudo yum update -y
$ sudo yum install -y awslogs
```

```:awscli.confの修正
$ sudo vi /etc/awslogs/awscli.conf

[default]
region = us-east-1
↓
[default]
region = ap-northeast-1
```

CloudWatchに送るログの指定を行っていきます。
デフォルトで/var/log/messagesを送る設定が記載されているので、それを修正して今回は/var/log/test.logを作成して、対象のログファイルとします。

```:awslogs.confの修正
$ sudo vi /etc/awslogs/awslogs.conf

[/var/log/test.log]
datetime_format = %b %d %H:%M:%S
file = /var/log/test.log
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = /var/log/test.log
```

```:サービス起動
$ sudo systemctl start awslogsd
```

```:サービス自動起動設定
$ sudo systemctl enable awslogsd.service
```

これでインストールと設定は完了になるので、動作確認を行います。

## 3. 動作確認
対象のログファイルに文字列を記載します。

```
$ sudo vi /var/log/test.log

aaaaaa
```

CloudWatchのログを確認します。
「CloudWatch」→「ログ」→「ロググループ」
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328551/0c9f4059-00fc-571a-cd8b-957d9b10dd2d.png)
awslogs.confのlog_stream_nameの値をインスタンスIDにしているので、「ロググループ」→「インスタンスID」配下にEC2のログが出力されています。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328551/52e8d8f6-2e9a-1f8e-b446-39dd4274c523.png)

awslogs.confの詳しい設定項目については公式を参考にしてください。
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/AgentReference.html
mkcertを使いRailsのローカル開発環境をSSL化する方法(for Mac)

### mkcertとは？ 

Railsの開発環境でHTTPSを有効にするためのツール。
Github( https://github.com/FiloSottile/mkcert#installation )には以下のように書かれています。

```
mkcert is a simple tool for making locally-trusted development certificates. It requires no configuration.

訳：mkcertは、ローカルに信頼された開発証明書を作成するためのシンプルなツールです。設定は不要です。
```

### mkcertをインストールする
homebrewを使っている場合のインストールコマンド

```
$ brew install mkcert

# ブラウザにFirefoxを使う場合は以下のコマンドも追加
$ brew install nss
```

```
# ローカルCA(認証局)を作成
$ mkcert -install
```

```
# 証明書を作成
$ mkcert localhost
```

![スクリーンショット 2020-04-21 21.59.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404519/87cac154-2bde-a595-5dc0-dec1ad2de2f9.png)
上から順に説明すると
■"/Users/ユーザーの名前/library/Application Support/mkcert"にあるローカル認証局を使っています
■"localhost"という名前で新しい証明書を作成しました
■証明書は".localhost.pem"に、鍵は".localhost-key.pem"にあります
ということです。

### puma.rbの設定を変更
ポートと、証明書と鍵を追記しましょう。

```
(中略)

if ENV.fetch('RAILS_ENV') { 'development' } == 'development'
  ssl_bind '0.0.0.0', '9292', key: './localhost-key.pem', cert: './localhost.pem'
end

(中略)
```

## 以上でHTTPS接続の設定は完了
https://localhost:9292/ にアクセスして、接続が可能か確認します。
これだけで接続可能になるとは非常に簡単ですね。

今回はMacのみのやり方について書きましたので、Mac以外の方はGithubにやり方が載っているのでそちらを参照ください。

## 参考
[mkcertのGithub](https://github.com/FiloSottile/mkcert#installation)
[Railsの開発環境でHTTPSを有効にする](https://blog.y-yagi.tech/posts/rails_ssl/)
[Railsの開発環境でhttps接続する！](https://tsubasa0105.hatenablog.com/entry/2019/02/16/191717)
KubernetesのServiceとPodのログを見る

## Podのログが見たい！

`kubectl logs -n [nameSpace] [podName]`が基本のコマンドです。

EnvoyがサイドカーとしてPodの中に入っている場合は、
`kubectl logs -n [nameSpace] [podName] -c [コンテナ名（アプリ名）]`で直接指定。

逆にEnvoyのログが見たい場合は
`kubectl logs -n [nameSpace] [podName] -c istio-proxy`でサイドカーのEnvoyのログが見える。

## Serviceのログが見たい！

 例えばIstioのingressGatewayのServiceにトラフィックが届いているのか確認したい場合に使えます。

`kubectl logs -n istio-system service/istio-ingressgateway`

#### よくサンプルで使われるbookinfoの場合はこのようになります。

`kubectl logs -n default service/productpage`

## kubectl logsの使えるオプション

- `kubectl logs -f -n [nameSpace] [podName]` 
tail -fと同じ挙動。常時流しておきたい場合に使用する。

- `kubectl logs --tail=10 -n [nameSpace] [podName]` 
tail -10と同じ挙動。最後の１０行だけ読みたい場合に使用する。

- `kubectl logs --since=1h -n [nameSpace] [podName]`
直近1時間のログを表示。時間で限定したい場合に使用する。他に`-since=3m`で3分前までのログを指定できる。
BEMとはなんぞや、、？

# BEMとは何か

Block Element Modifierの頭文字をとってBEM
Webサイトのコンポーネント化のためのフロントエンド設計方法のひとつで、厳格なclass名の命名ルールが特徴的な手法のこと。


# メリット
1.クラスの命名が簡単になる

2.要素の再利用がしやすくなる


# 意味・使い方
1.Block = 大元となるブロック要素。名詞を使用。

2.Element = Blockに属する子要素。名詞を使用。

3.Modifier = Block,Elementに特別な修飾をする。形容詞を使用。

[例]

```ruby

.main
  .main__header              # BlockとElementを繋ぐ際は、__(アンダースコア)２つで繋ぐ。
    .main__header--active       # Modifierに繋ぐ場合は、--(ハイフン)２つで繋ぐ
```
heroku slugsizeの削減

herokuでデプロイする際に、slugsizeに気を付ける必要があります。（現時点では500MB以下）
ググれば、slugsizeの削減方法が出てきます。
<b><u>それだけでもダメなら、djangoのrequirement.txtからインストールに必要のないパッケージを削除すればうまくいきます。僕の場合、Tensor-flowのサイズが大きく、原因でした。</b></u>
ブラウザ別のデフォルト検索エンジン

ブラウザによって、デフォルト検索エンジンが異なるので調べてみた。

## デフォルト検索エンジン別のブラウザ情報

###  デフォルト検索エンジンがGoogle
* Google Chrome
* FireFox
* Safari
* Opera
* CocCoc
* Brave
* Blisk
* Naver Whale 
* Lunascape Phoebe
* Maxthon


###  デフォルト検索エンジンがBing
* Internet Explore
* Microsoft Edge
* Amazon Silk(Kindle Fire)
* Vivaldi
* SRWare IRon
* Water Fox

### デフォルト検索エンジンがDuckDuckGo
* Tor Browser
* Falkon
* SeaMonkey

### デフォルト検索エンジンがYahoo.com
* Torch Browser
* Epic Browser

### デフォルト検索エンジンがYandex
* Yandex Browser 


### デフォルト検索エンジンが独自のもの
* Sleipnir


### 感想

圧倒的にGoogleが多いだろうと思っていたが、その通りだった。
Bingがデフォルト検索エンジンのブラウザもそこそこ存在するようだ。
あと、Naver Whaleのデフォルト検索エンジンがNaverではなく、Googleだった。



検索エンジンのシェアをstatcounterで見ると、圧倒的にGoogleが多い。

[Search Engine Market Share Worldwide
](https://gs.statcounter.com/search-engine-market-share)



BingなどのGoogle以外のSEOを気にした方が良いかは、サイトの利用状況に次第なのか。
年齢層が高いほど、Microsoft Edge(Bing)の利用が高くなるとか。
[BingのSEOを侮れない本当の理由｜Bingの対策で他社と差をつけよう]
(https://service.plan-b.co.jp/blog/seo/17804/)

Google向けの対策をしていればそれなりにBingでも良い結果は出るとのこと。
[BingのSEO対策はどうしたらいいの？](https://seolaboratory.jp/94325/)
WSL環境におけるNode.jsの導入から利用

#はじめに
投稿者の備忘録としての活用が主です。
Webの作成において役に立つNode.jsを導入します。

#環境
`wsl(Windows Subsystem for Linux)`にインストールします。

```
Editor: VSCode
Shell: bash version 4.4.20
Ubuntu: 18.04.4 LTS
```
#目次
1. nvmの導入[ >>](#1nvmの導入)
2. Node.jsの導入[ >>](#2nodejsの導入)
3. REPLを使ってみる[ >>](#3replを使ってみる)
4. ファイルを実行してみる[ >>](4ファイルを実行してみる)

#1.nvmの導入
Node.jsのバージョンを管理するためにまず`nvm`を導入します。
現在利用しているNode.jsのバージョンの把握
別バージョンへの切り替えなどを行えます。

```bash:wsl
$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash
```
終了したら、

```bash:wsl
$ source ~/.bashrc 
```
で、`.bashrc`の内容を読み込んでおきます。

```bash:wsl
$ nvm

Node Version Manager

Note: <version> refers to any version-like string nvm understands. This includes:
  - full or partial version numbers, starting with an optional "v" (0.10, v0.1.2, v1)
  - default (built-in) aliases: node, stable, unstable, iojs, system
  - custom aliases you define with `nvm alias foo`
以下略。。。
```
となれば、インストールが成功しています。

#2.Node.jsの導入
今回、Ver. 10.14.2 のNode.jsをインストールしました。

```bash:wsl
$ nvm install v10.14.2
```

```
Downloading and installing node v10.14.2...
Downloading https://nodejs.org/dist/v10.14.2/node-v10.14.2-linux-x64.tar.xz...
###################################################################### 100.0%Computing checksum with sha256sum
Checksums matched!
Now using node v10.14.2 (npm v6.4.1)
Creating default alias: default -> v10.14.2
```
```bash
$ nvm use v10.14.2
Now using node v10.14.2 (npm v6.4.1)
```
```bash
$ node --version
v10.14.2
```
指定したバージョンのNode.jsがインストールされていることを確認しました。

#3.REPLを使ってみる
Node.js版のコンソールだと思えばいいと思います。
(PythonのPythonコンソール的な感じ)
`Ctrl`+`c`二回でREPLを終了できます。

```console:REPL
$ node
> 1+1
2
>
(To exit, press ^C again or type .exit)
> 
```

#4.ファイルを実行してみる
プログラムの書き方は、`JavaScript`と同じかきかたをすればいいと思います。
今回単純な足し算プログラムを書いて動かします。
###ソースコード
```js:sum.js
'use strict';
function aAdd(num) {
    var res = 0;
    num[0] = 0;
    num[1] = 0;
    for (let s of num) {
        res += parseInt(s);
    }
    console.log(res);
}
aAdd(process.argv);
```
###実行結果

```bash:wsl
$ node sum.js 1 2 3 4
10
$ node sum.js      
0
```
###雑に解説
これは、引数の総和をとるプログラムでした。
`process.argv`に命令がリストとして入っています。
`$ node sum.js 1 1 1 2 3`を実行したとすると、
リストの中身は、

```console
[ '/home/yosse95ai/.nvm/versions/node/v10.14.2/bin/node',
  '/home/yosse95ai/sum.js',
  '1',
  '1',
  '1',
  '2',
  '3' ]
```
といった具合になっています。

だから、

>
    num[0] = 0;
    num[1] = 0;

の部分で数字以外の文字列部分(パス部分)を、`0`に置き換えてます。
多分もっとクレバーなやり方があると思います。

#おわりに
今回は、かなり初歩的な解説でした。
まだ自分が初心者なので、頭の整理を兼ねて書きました。
おそらく拙い文章でしたが、お付き合いいただきありがとうございました。
さよなら:wave:


#関連記事
- [Linux環境におけるNode.jsのためのyarn導入から利用](https://qiita.com/RoaaaA/items/28405818d2f14dc007b5)


#参考
- [N予備校 2020年 プログラミング入門](https://www.nnn.ed.nico/courses/668/chapters/9516)
macOS CatalinaでMySQL Workbenchが起動しなくなった時にすること 

macOS Catalinaにアップデートしてから、[MySQL Workbench](https://www.mysql.com/jp/products/workbench/)が起動しなくなってしまって困ってたのが、やっと解決。

スタンドアロンで動くし、データベースを使う使わないに関わらず、設計・分析時のE-R図作成ツールとしても重宝してるので、使えないとかなり不便。

というわけで、コマンドラインで直接実行してみて以下のようなエラーが出て起動しない場合の処方箋。

```
$ /Applications/MySQLWorkbench.app/Contents/MacOS/MySQLWorkbench

your pythonpath points to a site-packages dir for python 3.x but you are running python 2.x! pythonpath is currently: "/applications/mysqlworkbench.app/contents/resources/libraries" you should `unset pythonpath` to fix this.
```
launchdからのアプリ起動時にPython2のライブラリを呼び出すように環境変数を設定するのが解なので、~/Library/LaunchAgents/jp.co.cyberz.forMySQLWorkbench.plist に以下のファイルを作って、ログアウト→ログインで解決。
もちろん無保証。


```~/Library/LaunchAgents/jp.co.cyberz.forMySQLWorkbench.plist
<!--
===== No guarantee!! =====
NAKABAYASHI Toshifumi
http://www.cyberz.co.jp/index.php/staff/
===== No guarantee!! =====

(1)place this file
 ~/Library/LaunchAgents/jp.co.cyberz.forMySQLWorkbench.plist

(2) logout and login
-->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>jp.co.cyberz.forMySQLWorkbench</string>
    <key>ProgramArguments</key>
    <array>
      <string>/bin/launchctl</string>
      <string>setenv</string>
      <string>PYTHONPATH</string>
      <string>/usr/local/lib/python2.7/site-packages/</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
  </dict>
</plist>
```

MySQL Workbenchはシステムデザインに最良のツールの一つ。
それにしても新しいサービスの設計考えるの楽しいよね
JQueryの基本の基本

#Jqueryのきほん

#####使う方法
・ダウンロードする
or
・CDNを利用してCDNからJQueryを読み込んで、使用する。ただしインターネットに繋がっていないと使えない。

#####書き方

$('#HTMLのid名')→これでDOMをとってくる


#####イベント設定
・イベント用メソッド使用
ex .click();

・onメソッド使用
対象要素.on( イベント名, セレクタ(任意), データ(任意) ,function() {処理内容} )

セレクタを選択する事で、対象要素の下にあるセレクタの部分に対してイベント設定ができる。

#####ajax
ajaxを使用する時は、

```javascript

$.ajax({
送りたいurl,メソッド(基本post),データor受け取るデータタイプの指定
})
.done((data) { //ここでは成功した場合 dataとはajaxでのレスポンスで返ってきた値
//処理
}) .fail((data) {//ここでは失敗した場合
//処理
)
```

こちらを参考にさせていただきました。[はじめてのAjax(jQuery) 2018年版](https://qiita.com/zakiyamaaaaa/items/bdda422db2ccbaea60d9)

またAjaxで指定するURLに変数を埋め込む場合は、以下のように埋め込む。下の例は一覧表示されているリストから削除申請をAjaxで投げるときに使用。

```javascript
$('.delete_word').on('click', function () {
    var id = $(this).data('id');
    if (confirm('Are you sure?')) {
      $.ajax({
        url: '/words/' + id, //このように埋め込む
        type: 'POST', 
        data: {
          'word_id': id,
          '_method': 'DELETE'
        }
      })
        .done((data) => {
          $('#word_' + id).fadeOut(800);
        }).fail((data) => {
          alert('通信に失敗しました');
      })
    }
  });
```

サーバ側で値を返したい時は以下のようにする（phpの場合）。headerでHTTpヘッダの中身を指定し返し、json_encodeで引数をjsonの形にして返すことになる。

```php

else {
          header("Content-Type: application/json; charset=UTF-8");
          $data = [
          'failedMsg' => 'お気に入り登録or解除に失敗しました'
          ];
          echo json_encode($data);
          exit;
      }
```

#####その他
JSとは同じ内容でも書き方が異なるので注意する


$('#HTMLのid名').valは、その要素の値valueを引き出す。

$('#HTMLのid名').data(data-OOのOOの部分)で、HTMLでdata-OOとして定義されている属性の中身を得る。
【Visual Studio Code】JSONを整形する方法

#はじめに
JSONをパッと見やすく整形したい時ってありますよね。それ...
###『Visual Studio Code』で簡単にできますよ


#やり方
1. 新しいファイル作成（Mac：`cmd` ＋ `n`  または タブのところを2回クリック）
2. 1行のJSONを貼り付け
3. 言語モードをJSONにする（Mac：`cmd` ＋ `k`押した後`m`）
4. 右クリックで『ドキュメントのフォーマット』を選択（Mac：`option` ＋ `shift` ＋ `L`)

〜整形前〜
<img width="1070" alt="JSON整形前.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573011/feec61f2-e6f8-2cb9-b99c-782ba2177e85.png">


〜整形後〜
<img width="519" alt="JSON整形後.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573011/774511d3-bfa7-ae44-411d-e19d39a99956.png">

**ズキュゥゥゥン**


##ちなみに
スペースを取り除く
`^[ \t]+`

改行を取り除く
`[\r\n]+`

こちらで元の状態に戻せます。
react-redux-firebase を導入しようとしたときに起きた@@reactReduxFirebase/LOGINのエラーを消したメモ

### 概要
* react-redux-firebase を使ってCRUD を試してみた
  * 一応動いた。。。が、使いこなせてない感。
* そのまま導入すると、以下のエラーが発生。

```
index.js:1 A non-serializable value was detected in an action, in the path: `auth`. Value: 

Take a look at the logic that dispatched this action:  {type: "@@reactReduxFirebase/LOGIN", auth: P, preserve: undefined} 
```

* 以下のようにgetDefaultMiddlewareのオプションを指定することででエラーを消すことができた。

```diff
import {
  configureStore,
  getDefaultMiddleware,
  EnhancedStore,
} from '@reduxjs/toolkit'
import { rootReducer } from './rootState'
import logger from 'redux-logger'

export const setupStore = (): EnhancedStore => {
  const middlewares = [
    ...getDefaultMiddleware({
+      serializableCheck: {
+        ignoredActions: ['@@reactReduxFirebase/LOGIN'],
+      },
    }),
  ]
```

[CRUD追加時のソース](https://github.com/hibohiboo/create-now/tree/a33dc56dce0d99e4703a924fb0c9af1b26d62ce3/) 

## 参考

[React + Redux + Firebase を使ってログイン機能あり掲示板アプリ開発②](https://qiita.com/momosuke/items/57295ca99387ab243ce8)
[Docker で zeit nowのデプロイ環境とNext.jsの開発環境を作ったメモ][*1]
[PdfMakeを使ったPDF作成APIをZeit Nowで動かしたメモ][*2]
[react-redux-firebase](http://react-redux-firebase.com/)
[react-redux-firebase useFirestore.md](https://github.com/prescottprue/react-redux-firebase/blob/master/docs/api/useFirestore.md#usefirestore)
[error @@login](https://github.com/rt2zz/redux-persist/issues/988)
[firestore](http://react-redux-firebase.com/docs/firestore.html)
[Zeit Now + Next.js のページにFirebase認証を導入した際、環境変数にハマったメモ](https://qiita.com/hibohiboo/items/6edf851b3a5dc6601b37)


[*1]:https://qiita.com/hibohiboo/items/e6c30e76e26dde0e8611
[*2]:https://qiita.com/hibohiboo/items/9123fc6ecb546c5820e3
[*3]:https://qiita.com/hibohiboo/items/11768cb10bf1e7025090
【Mask R-CNN】AttributeError: module 'tensorflow' has no attribute 'log' を解決した話。

###※2020/05/18追記
下記の記事で新しい解決方法を紹介しています！

[Mask R-CNNのdemoでtensorflowのバージョンをダウングレードした話。] (https://qiita.com/skperfarming/items/f1442b0d45dd02e348c9)


#Mask R-CNNを実装してみたかった

**深層学習超初心者**がエラーを解決した話です。
誰かの助けになればと思い、記事を書きました。

画像認識でMask R-CNNを使ってみたい場合、matterport社のMask_RCNNというコードを利用するのが近道です。

https://github.com/matterport/Mask_RCNN

これだけ読んでも良くわからなかったので、下記のサイトを読みながら、
Google colaboratory上でdemo.ipynbを実行しようとしました。

https://tech-blog.optim.co.jp/entry/2019/03/28/173000
http://maruo51.com/2020/02/22/mrcnn/

しかし！
そのまま実行しようとしても、

```
AttributeError: module 'tensorflow' has no attribute 'log' 
```

が発生してしまうのです。（2020年4月20日時点）

そこで、これを解決するために2日間くらい試行錯誤したので、
書き記しておきます。

#解決方法（仮）

参考になるのは、以下に示すgithubのお悩み相談箱みたいなものです。

https://github.com/matterport/Mask_RCNN/issues/1797#

全部英語なのですが、頑張って読み進めたところ、ヒントになるような投稿を見つけました。

```
tf.log() -> tf.math.log()
tf.sets.set_intersection() -> tf.sets.intersection()
tf.sparse_tensor_to_dense() -> tf.sparse.to_dense()
tf.to_float() -> tf.cast([value], tf.float32)
```

どうやら、tensorflowのバージョンが違ってメゾットが変更になっていることに起因するエラーのようです。

この通りに、mrcnn/model.pyの該当箇所を書き直せばいいはずです。

#注意点！

注意すべきは、エラーが出る最後まで行ってからmodel.pyを変更するのではなく、
**最初にレポジトリをクローンした直後にmodel.pyを書き換えてしまうこと**です。

**修正後のmodel.pyでsetupとかを進めることで解決**できたようでした。
（なんか、その場しのぎな解決方法な気がするので、
本当の原因を知っている人がいたら教えてください。）

一件落着！
参考になったらいいねお願いします！
良く忘れるcode集 part1

#HTML & CSS
良く忘れるやつ集：初級編

1.余白

```css:yohaku.css
.inout{
padding:1px;
border:1px;
margin:1px;
```

この順で内から外に広がります

2.お問い合わせ

```html:form.html
<p>小記入欄</p>
<input>

<p>大記入欄</p>
<textarea></textarea>

<p>保存のボタン</p>
<input type="submit" value="保存">

```

次回、中級編やります
【初心者でもできる‼】Javadocの書き方

## 1.事前知識
- [【最新】UbuntuでJavaの環境を構築する方法](https://qiita.com/ryome/items/37c53e9638a9c6ea146a)

または

- [【初心者でもできる‼】Windows10にJava環境を作る方法（JDK14.0.1）](https://qiita.com/ryome/items/30135570954e36196821)

事前知識として、上記リンクの内容が必要です。


## 2.Javadocとは
- `Javadoc`　とは、サン・マイクロシステムズが開発したコンピュータソフトで、Javaのソースコードから `HTML形式のAPI仕様書` を生成するものである。
- Javadocコメントは `/**` と `*/` の間に `コメントを記述` する。

## 3.Javadocの書き方とドキュメント作成

```java:Sample.java
/**
 * @author 作成者名
 * @version x.x.x
 */
 
 /**
  * Javadocの解説用メインクラス
  */
public class Sample {
    /**
     * mainメソッド
     * @param args 使用しない
     */
    public static void main(String[] args) {
        // 文字列の表示
        System.out.println("JavaDocサンプル");
    }
}
```

- 上記の文をコピーして、文字コードは `S-JIS` を指定し、ファイル名を `Sample.java` で保存し、コマンドプロンプトで `javadoc -d html Sample.java` を実行します。↓↓

``` bash

$ javadoc -d html Sample.java

```

- 結果は以下のようになります。

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/d2495818-8072-9b2e-6745-d336c94c707c.png)

- `html` フォルダが作成されていることを確認します。　
　　　　　　　　　　　　　　　　　　　　　　　　　
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/64fa02f5-9a1e-683d-dd62-8fce4b29e01c.png)

- `html` フォルダ内の `index.html` を開きます。　

![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/0bb55d18-d1b2-c674-20d5-bd56b1c610ec.png)

- ブラウザが起動し、 `Sample.html` が表示されます。

![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/600bb40f-e76a-a062-2b7e-d84f1296237c.png)

- 画像のように表示されれば成功です。

## 4.GitHub
GitHubにソースコードを公開しています。

https://github.com/ryomeblog/qiita/tree/master/%E3%80%90%E5%88%9D%E5%BF%83%E8%80%85%E3%81%A7%E3%82%82%E3%81%A7%E3%81%8D%E3%82%8B%E2%80%BC%E3%80%91Javadoc%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96%B9


## 5.関連
- [【最新】UbuntuでJavaの環境を構築する方法](https://qiita.com/ryome/items/37c53e9638a9c6ea146a)
- [【初心者でもできる‼】Windows10にJava環境を作る方法（JDK14.0.1）](https://qiita.com/ryome/items/30135570954e36196821)
- [【初心者でもできる‼】Windows10にEclipseをインストールする方法（Java環境構築）](https://qiita.com/ryome/items/b47c5acdaa52cffbec58)
targetSdkVersion を 29 に上げても Robolectric のテストを動くようにする

# 概要
Java 8 の環境で targetSdkVersion を 29 に上げたら RobolectricTestRunner を使うユニットテストが動かなくなったので、対応方法を調べました。

## 問題
テストを実行すると、以下の例外が出てテストが失敗します。

```
java.lang.IllegalArgumentException: failed to configure jp.toastkid.yobidashi.media.image.preview.RotateMatrixFactoryTest.test: Package targetSdkVersion=29 > maxSdkVersion=28
	at org.robolectric.RobolectricTestRunner.getChildren(RobolectricTestRunner.java:240)
	at org.junit.runners.ParentRunner.getFilteredChildren(ParentRunner.java:426)

// 中略

	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.IllegalArgumentException: Package targetSdkVersion=29 > maxSdkVersion=28
	at org.robolectric.plugins.DefaultSdkPicker.configuredSdks(DefaultSdkPicker.java:118)
	at org.robolectric.plugins.DefaultSdkPicker.selectSdks(DefaultSdkPicker.java:69)
	at org.robolectric.RobolectricTestRunner.getChildren(RobolectricTestRunner.java:206)
```

## 対応
現時点の最新バージョンの 4.3.1 を使えば SDK 29に対応はしているようですが、Java 9 以上が必要です。

```
java.lang.UnsupportedOperationException: Failed to create a Robolectric sandbox: Android SDK 29 requires Java 9 (have Java 8)

	at org.robolectric.RobolectricTestRunner.getSandbox(RobolectricTestRunner.java:265)
	at org.robolectric.RobolectricTestRunner.getSandbox(RobolectricTestRunner.java:63)
	at org.robolectric.internal.SandboxTestRunner$2.evaluate(SandboxTestRunner.java:215)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
```

## Workaround
諸事情で Java 8 を使わざるを得ない場合は、 src/test/resources/robolectric.properties というファイルを置き、以下の設定を入れることで動くようになりました。Java 9 を導入するまではこれで対応しましょう。

```:robolectric.properties
sdk=28
```

今後、sdk 28を指定していたことでテストに不具合が起こる可能性も否定はできないので、早めに Java と Robolectric をアップグレードする方が良さそうです。

## 参考
- [Robolectric and Android SDK 29](https://stackoverflow.com/questions/56808485/robolectric-and-android-sdk-29)
Office 365 の試用版を1ヶ月間使い倒す(テナント作成編)

昨今の時世より、テレワークや働き方改革に対する動きが各企業でも見られ始め、様々なソフトウェアが注目を集めてきています。
その中でも比較的検討されやすい"Office 365"とは一体どんなものなのか、色々触って検証してみようと思います。

## 試用版の種類
様々なソフトウェア会社やWebサービス会社では、無料版(便宜上、試用版も無料版と同様に扱います)と有料版で区分けをすることで、気軽に試しつつ、顧客になってもらう努力がなされています。

実際問題、無料版をユーザが使っても、企業には文字通り1円も入らないことがほとんどなので、戦略上、無料版と有料版には様々な違いを施し、有料版への敷居を低くする傾向があります。

ここで、無料版と有料版でどのように違いを出しているのか、大きく2種類に分けてみました。

1. フル機能が期間限定で使える  
    Office 365 や G Suite など 
1. 機能を限定して無期限に使える  
    Slack や zoom など

今回無料版で使っていくOffice 365は前者の"フル機能が期間限定で使える"ものになります。

## 試用版テナントの作成
さっそくテナントを作っていきます。[^1]

[^1]: テナントとは、会社単位で作る概念になります。会社=テナントで、従業員=アカウントのイメージです。

1. [Office 365のURL](https://www.microsoft.com/ja-jp/microsoft-365/business/office-365-enterprise-e5-business-software?activetab=pivot%3aoverviewtab)にアクセスします。

1. 画面右下の無料試用版をクリックします。[^2]
<img width="1349" alt="o365e51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624131/10b625c9-796f-a20b-6cfe-5fbf1dceec79.png">

    <details>
    <summary>ブラウザのキャッシュで既に別のアカウントが紐づいていた場合
    </summary>
    <div>

    このような画面が出てきますが、気にせず "新しいアカウントを作成" をクリックしてください。(自動的にサインアウトして、次の項目の画面に進みます)
<img width="609" alt="o365e52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624131/4b78ca70-f37a-29c1-516f-a51396175e51.png">


    </div>
    </details>

1. 既に所有している任意のアドレスを入力します。
<img width="667" alt="o365setup1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624131/b4bcf9e7-b056-446a-0afe-07e6fab495e5.png">

  
1. 出てきたメッセージは気にせず、"新しいアカウントを作成"をクリックします。
<img width="653" alt="o365setup2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624131/b0435019-1808-4c9d-515b-5ed28e3a8f62.png">


1. 管理者になる人(自分)の氏名や電話番号(プライベート、使い回しOK)を入力して、"次へ" をクリックします。
<img width="639" alt="o365setup3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624131/c8ba9377-3f56-5e89-33e3-89f50a3c0e5e.png">

1. 前項の電話番号に確認コードを送信して、送信された確認コードを入力します。
<img width="596" alt="o365setup4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624131/b67dc0c6-d578-5d8a-1e6f-e21d05ca1e82.png">

1. 試用版で使用するドメイン(@マーク以降)を任意に決めて、利用可能かどうか(ユニークかどうか)を確認します。
<img width="672" alt="o365setup5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624131/ef856e00-fb14-36ce-6d1b-10dc2554cb6c.png">

1. 管理者アカウントのアドレスとパスワードを決め、"サインアップ" をクリックします。
<img width="666" alt="o365setup6.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624131/9d660cde-27e5-62fb-6430-3fd39310a23d.png">


これで試用版テナントの作成が完了です。
"設定に移動" でテナントの設定をします。
<img width="596" alt="o365setup7.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624131/d63c6732-36d9-6ec6-481d-a184869436d8.png">


次回に続く

[^2]: 今回はOffice 365 E5というプランを使用しています。E5が大企業向けで1番機能が充実したものになります。(2020年4月21日現在)
【Day57】積み上げ日記

##予定
■Udemy（有料教材）
－セクション11～14

##完了
■Udemy（有料教材）
−セクション１１、１２

##学習時間
６h

##学習ポイント
■TableView
リスト型のパーツのこと

■TableView構築に必要なメソッド
・セルの数を決めるメソッド
・セルのセクション数を決めるメソッド
・セルを構築する際に呼ばれるメソッド
・セルの高さを決めるメソッド
・セルがタップされたときの呼ばれるメソッド

##疑問点
■103

##参考記事
https://ja.stackoverflow.com/questions/12716/tableview%E3%82%BB%E3%83%AB%E7%95%AA%E5%8F%B7%E3%82%92indexpath%E3%81%A7%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%82%92%E3%82%8F%E3%81%8B%E3%82%8A%E3%82%84%E3%81%99%E3%81%8F%E8%A7%A3%E8%AA%AC%E3%81%8A%E9%A1%98%E3%81%84%E3%81%97%E3%81%BE%E3%81%99