OmniAICreator/Qiita-1.07M huggingface dataset:
VueRouterを使ってみる

##基本
###セットアップ
```zsh
$ vue create router-vuecli
$ cd router-vuecli
$ npm i vue-router
$ touch src/router.js
```
```src/router.js
import Vue from 'vue'
import Router from 'vue-router'

//vueにプラグインを適用する
Vue.use(Router)

export default new Router({
  routes: [
    //ここにパスを書いていく
  ]
})
```
```diff:src/main.js
import Vue from 'vue'
import App from './App.vue'
+ import router from './router'

Vue.config.productionTip = false

new Vue({
+   router,
  render: h => h(App),
}).$mount('#app')
```
```src/App.vue
<template>
  <div>
    <router-view></router-view>
  </div>
</template>
```

###ページを作る
```zsh
$ mkdir src/pages
$ touch src/pages/Home.vue
$ touch src/pages/Users.vue
```
```src/pages/Home.vue
<template>
  <div>
    <h1>Home</h1>
  </div>
</template>
```
```src/pages/Users.vue
<template>
  <div>
    <h1>Users</h1>
  </div>
</template>
```
```diff:src/router.js
import Vue from 'vue'
import Router from 'vue-router'
+ import Home from './pages/Home'
+ import Users from './pages/Users'

Vue.use(Router)

export default new Router({
  routes: [
+    { path: '/', component: Home },
+    { path: '/users', component: Users }
  ]
})
```

##オプション
###URLから#を無くす
```diff:src/router.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from './pages/Home'
import Users from './pages/Users'

Vue.use(Router)

export default new Router({
+  mode: 'history',
  routes: [
    { path: '/', component: Home },
    { path: '/users', component: Users }
  ]
})
```

###リンクで行き来できるようにする
`a`タグを使うと毎回サーバーにリクエストを投げてしまうので、`router-link`を使う

```diff:src/App.vue
<template>
  <div>
+    <nav>
+      <router-link to='/'>Home</router-link>
+      <router-link to='/users'>Users</router-link>
+    </nav>
    <router-view></router-view>
  </div>
</template>
```

###メソッドでページ遷移する
関数を作り、`this.$router.push`を使う

```diff:src/pages/Home.vue
<template>
  <div>
    <h1>Home</h1>
+    <button @click='toUsers'>Usersのページに移動</button>
  </div>
</template>

+ <script>
+ export default {
+   methods: {
+     toUsers() {
+       this.$router.push({ path: 'users' })
+     }
+   }
+ }
+ </script>
```

###動的なURLに遷移する
`example.com/users/17`的なURLに遷移できるようにします

```diff:src/router.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from './pages/Home'
import Users from './pages/Users'

Vue.use(Router)

export default new Router({
  mode: 'history',
  routes: [
    { path: '/', component: Home },
-    { path: '/users', component: Users }
+    { path: '/users/:id', component: Users }
  ]
})
```
もちろん`:id`の部分の文字列を拾って使うことも可能です。`$route.params.hoge`を使います。

```diff:src/pages/Users.vue
<template>
  <div>
    <h1>Users</h1>
+    <p>User NO. {{ $route.params.id }}</p>
  </div>
</template>
```

##参考
- [超Vue JS 2 完全パック - もう他の教材は買わなくてOK！ (Vue Router, Vuex含む) | Udemy](https://www.udemy.com/course/vue-js-complete-guide/)
ApacheのリバースProxyで、振り分け先に認証Proxy経由で転送する

#ApacheのリバースProxyで、振り分け先に認証Proxy経由で転送する

## やりたいこと
イントラネット内にあるWebサーバをリバースProxyとして、リクエストをインターネット上にあるサーバに振り分けたい。
振り分け先サーバはインターネット上にあり、イントラネットからの通信はProxy(Basic認証)を経由する。

## 構成図
![構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85440/5d1884ff-43e8-439c-fedf-255664a9c84c.png)

## 要約
Apacheの設定ファイルに以下のように書けばできる

```conf
ProxyRequests Off
ProxyPass [Webサーバで受け付けるパス] [振り分け先]
ProxyPassReverse [Webサーバで受け付けるパス] [振り分け先]
ProxyRemote [Proxyを通す対象] [ProxyのURL]
Header add Proxy-Authorization "Basic [認証ProxyのID:PWをbase64エンコードした文字列]"
```

設定例

```conf
ProxyRequests Off
ProxyPass / http://xxx.xxx.xxx.xxx:3000
ProxyPassReverse / http://xxx.xxx.xxx.xxx:3000
ProxyRemote * http://192.168.20.5:8080
Header add Proxy-Authorization "Basic dXNlcm5hbWU6cGFzc3dvcmQ="
```

## NGだった指定方法

```conf
ProxyRemote * http://username:password@192.168.20.5:8080
```
ProxyのURLにID/PWを書いてもいけるのではないか・・・と思ったけど、
Apache起動時に以下のエラーになった。

```
ProxyRemote: Bad syntax for a remote proxy server (bad port number)
```

どうやら```username:password```の```:```をポート番号の区切り文字と認識されて
```password@192.168.20.5:8080```は、ポート番号の形式としてNGと判定されたっぽい


## 参考
https://httpd.apache.org/docs/2.4/ja/mod/mod_proxy.html
https://httpd.apache.org/docs/2.4/ja/mod/mod_headers.html
https://qiita.com/charon/items/5406c23494eeee733dc1
https://www.server-world.info/query?os=CentOS_7&p=httpd2&f=2
gitで変更ファイルだけaddしたいとき　git add -u 

#結論:git add -u　を使おう
```
git add - u
```

#想定状況
- 既にpushしたけど微妙な修正内容がある
- ディレクトリ構造が複雑で一個一個指定するのが面倒かつ全部addするのは重い

#実行例
ファイル変更後はこういう状況
![スクリーンショット 2020-04-08 20.12.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493311/53efcf03-fe5b-fc4b-02ad-083115e55915.png)

ここで

```
git add - u
```
を使うと、
![スクリーンショット 2020-04-08 20.12.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493311/0ef7870e-fa85-ec4a-07c5-5a0aad78deb0.png)

と、変更した三つのファイルだけaddできているのがわかる。最後はcommitしてpushしてあげれば終了！
JuliaをUbuntu18.04にインストールしてPyCharmで実行するまで

#いきさつ
juliaの勉強をするためにUbuntuで環境構築したが、すこしつまづいたので備忘録として。
#Dependencies
- Ubuntu 18.04 LTS
- Julia v1.4.0
- Pycharm 2019.3.4  

#手順
1.Juliaを[公式サイト](https://julialang.org/downloads/)からダウンロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442000/ee43533e-d1b0-b84a-bfa3-91aab4ed9615.png)
　今回は上図のGeneric Linux Binaries for x86の64-bit(GPG)をダウンロードして解凍します。

```terminal
$ cd ダウンロード
$ tar xzvf julia-1.4.0-linux-x86_64.tar.gz
$ rm *.gz #gzファイルを処分
```

2.その後解凍後のディレクトリを/opt/に移動します

```terminal
$ sudo mv ~/Downloads/julia-1.4.0 /opt/
```

3.bashrcにパスを追記

```terminal
$ sudo vim ~/.bashrc # PATH="$PATH:/opt/julia-1.4.0/bin"を末尾に加える
$ source ~/.bashrc
```

　この時点で端末で$ juliaを実行するとJuliaが起動するようになっていると思います。
4.**PycharmにJuliaのextensionをインストール**
　ここで詰まった。Ctrl+Alt+Sから開くSettingsタブにPluginsの項目があり、ここを押下するとインストールできるPluginの一覧が見れる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442000/59fc3077-9d59-ebd5-1221-708ac374e691.png)
　検索窓にjuliaと打ち込むとJuliaのプラグインも出るのだが、ここからインストールするとエラーが出る。
　[Plugin "Julia" requires missing "com.intellij.modules.java". #446](https://github.com/JuliaEditorSupport/julia-intellij/issues/446)
　結論から言うと、[パッチをあてたzipファイル](https://github.com/JuliaEditorSupport/julia-intellij/files/3942247/julia-intellij_0.4.1_patched.zip)を作成してくれているのでそれをダウンロードすればよい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442000/557a4dd6-5153-7e51-5469-7f23fd3305ba.png)
　そして先ほどのタブのMarketplace, Installedの隣にある歯車マークをクリックすると、Install Plugin from Disk...が表示されるので、そこからzipファイルを選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442000/efdf6fbe-a8b4-067a-3b0a-0b4f3859c4f3.png)
　Install(緑のボタン)がRestartに変わるはずなので、そこを押して再起動する。
5.Juliaプロジェクトを立ち上げる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442000/c87c501c-2af2-f4e2-5713-621db307e049.png)
　新規プロジェクトを立ち上げると、このようにJuliaが選べるようになっている。Select Julia executableに先ほどインストールしたJuliaを選んでCreateする。
6.Juliaの設定を行う。
　再度Ctrl+Alt+SでSettingsを開いて、Juliaの設定をする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442000/6820239f-0ff6-a2c6-f369-88b38be28f97.png)
おそらくJulia base path:がこのように空になっていると思われるので、Refresh base/import path（上の青くなっているところ）を押すとパスが自動設定される。Applyを押してウィンドウを閉じる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442000/fb6230de-54a4-7245-d5c3-992c73b80c2e.png)
7.Juliaファイルを作成
　Pythonと同様の手順でプロジェクトに.jlファイルを新規作成。右クリックででてくるJulia Fileを選ぶ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442000/49545308-8e0d-daf6-5b52-169a4b39f859.png)
空のファイルに以下のテストコードをコピペする。

```test.jl
function func()
    i = 10
    while i>0
        println(sin(i))
        i-=2
    end
end

func()
```

8.実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442000/f40a1b59-3bbf-df54-b407-29a886722904.png)
　上の実行ボタン（緑の▲）が押せるようになっているはずなので、そこから実行。下のRunに図のような実行結果がでていればOK.

#まとめ
　デバッグ実行もできるらしいが、詰まったのでまた次回。

#参考
[今噂のJuliaをUbuntuにインストールしてJupyter Notebookで使おう！](https://qiita.com/__8oki__/items/4401bb6a8249916f1302)
[youtube-dl] python3のSSLエラー(CERTIFICATE_VERIFY_FAILED)

## 背景

次のようにyoutube-dlのコマンドを叩くと，`SSL: CERTIFICATE_VERIFY_FAILED`のエラーが吐かれてしまうことがあります．それについての原因と解決策と書いていきます．

```
youtube-dl `url`

ERROR: Unable to download webpage: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1045)> (caused by URLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1045)')))
```
どうやらpyhon3.6の不具合で，証明書のパスが通らなくなってしまうことがあるみたいです．
バグの詳細が気になる方はpython3.6のbugtrackerは[こちら](https://bugs.python.org/issue29065#msg283984)です．


# 解決策1
最も簡単な方法はSSLでエラーが起きているなら，HTTPで通信するということです．
コマンドに`--no-check-certificate`のオプションをつけることでSSL証明書なしでダウンロードできます．

```
youtube-dl `url` --no-check-certificate
```

# 解決策2
やっぱりSSLで通信したほうがいいよねと思う方もいることでしょう．
証明書のパスが通っていないので，通せばいいだけです．

`certifi`というパッケージが簡単にpython3.6の証明書の場所を教えてくれます．

```
pip3 install --upgrade certifi
```

簡単にpython3のインタプリタでパスを尋ねます．

```
>>> import certifi
>>> certifi.where()
'/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/certifi/cacert.pem'
```

これでpemファイル(SSL証明書)の場所が分かったので，パスを通します．

```
export SSL_CERT_FILE=/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/certifi/cacert.pem
```

これでパスが通ったので，無事にSSLのエラーがなく，youtube-dlのコマンドを使うことができます．exportなので，bashrcやzshrcなどに書いておくと便利かもです．

# Reference

[StackOverflow Certificate Verification Failure for youtube-dl](https://stackoverflow.com/questions/48064876/certificate-verification-failure-for-youtube-dl)

[SSL certificate verify failed #4816](
https://github.com/ytdl-org/youtube-dl/issues/4816)
[Unity] VRでPost Processing StackのVignetteが２分割されてしまう時の対処法

#はじめに
ゲームなどでダメージを受けたときに周りが赤くなる表現をVRで作ろうと思ったところ，思ったようにうまくいかず小一時間ほどはまったので共有します．

#環境
windows10
unity2019 1.4f1
Oculus Integration ver1.44
Oculus rift s

#問題のシーン
![ダメージ２分.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610785/80b6e521-1eb9-65b9-5029-2d4aa515e886.png)


周囲だけ赤くしようとしたはずが2分される

#解決策
・PlaySettingを開いてXRSettingにあるStereoRenderingModeをマルチパスからシングルパスにする
![シングルパス.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610785/1220740b-aab3-f2be-8f50-efa1d344da44.png)


###マルチパスのままで解決したい場合
・Packag/PostProcessing/RunTime/PostProcessingRenderer.csを開く
・48行目のnumberOfEyesを2から1に変更する

```c#

if (stereoRenderingMode == StereoRenderingMode.SinglePass)
                    {
                        //numberOfEyes = 2;
                        numberOfEyes = 1;
                        xrDesc.width /= 2;
                        xrDesc.vrUsage = VRTextureUsage.None;
                    }
```

#設定後
![ダメージ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610785/facbb893-6fda-158d-cb42-04bdebcd1f29.png)
【GAS】Gmailへの特定のメールを正規表現を使いながらスプレッドシートに転記する

Qiita初投稿です。ノンプログラマですが、いつも記事を楽しく読んでいます。
プログラミングの知識が不足しており、汚いかもしれませんが、ご容赦ください。



## コード

```qiita.js
//シートを取得する。
var sheet = SpreadsheetApp.getActiveSheet();

function getMail() {
  
  // メール検索する文字列：今回は件名の【HP問合せ】
  var str = "HP問合せ";
  
  // 上記の文字列に合致するスレッドを取得(とりあえず100件取得します)
  var threads = GmailApp.search(str,0,100);
  
  // メッセージを取得する
  var messages = GmailApp.getMessagesForThreads(threads);
  
  for(var i = 0; i < messages.length; i++){
    for(var j = 0; j < messages[i].length; j++){
      
      //メッセージIDを取得(重複を防ぐため)
      var messageId = messages[i][j].getId();
      
      //もし、スプレッドシートに存在したら実行しない
      if(!hasId(messageId)){
       //メール受信日時を取得
       var mailDate = messages[i][j].getDate();

       // メッセージの本文をプレーンテキストで取得
       var body = messages[i][j].getPlainBody();
           
       //正規表現をつくる
       var regName = new RegExp('氏名 :' + '.*?' + '\r' );
       var regMail = new RegExp('メールアドレス :' + '.*?' + '\r' );
       var regTel = new RegExp('電話番号 :' + '.*?' + '\r' );
       var regMemo = new RegExp('備考 :' + '.*?' + '\r' );
      
       //正規表現をマッチさせたうえで、転記するときに、
       //セルに"お名前："などが入らないように、正規部分を削る
       var Name = body.match(regName)[0].replace("氏名：","");
       var Mail = body.match(regMail)[0].replace("メールアドレス :","");
       var Tel = body.match(regTel)[0].replace("電話番号 :","");
       var Memo = body.match(regMemo)[0].replace("備考 :","");

       //セルに行を追加する(ID、日時、氏名、アドレス、電話番号、備考)
       sheet.appendRow([messageID,mailDate,Name,Mail,Tel,Memo]);
       }
     }
  }      
}

// 同じIDのメールは転記しないようにするため、すでにIDがあるかどうか調べる関数
function hasId(id){  
   //今回は1列目にメールIDを入れていくので1列目から探す
    var data = sheet.getRange(1, 1,sheet.getLastRow(),1).getValues();
    var hasId = data.some(function(value,index,data){
   //コールバック関数
    return (value[0] === id);
  });
  return hasId;
}

```

一旦、出来上がりました。
1日に2回発動するようにトリガーも設定しました。
トリガーの設定は以下のようなものです
[【GAS】トリガーの設定](https://qiita.com/kakeru0520sou1/items/a82165446b0932f63c5b)


##参照したもの

**書籍**
[Google AppScript完全入門](https://www.amazon.co.jp/Google-Apps-Script%E5%AE%8C%E5%85%A8%E5%85%A5%E9%96%80-%EF%BD%9EGoogle-Suite%E3%81%AE%E6%9C%80%E6%96%B0%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%82%AC%E3%82%A4%E3%83%89%EF%BD%9E-ebook/dp/B07BNB1Z9L)
関数の意味などを調べる用に辞書的に使いました。
作者の高橋さんは、日本のGASリテラシー向上に最も貢献している人に違いない。

GAS勉強しようと思ったとき、おそらくこの本が一番情報量が多いです。

ただ、一からこれ見て勉強するやり方よりも、自分がやりたいことの似たような例をググりながら、辞書的にこの本を参照するのが一番良いと思います。



**ブログ**
[GASでフォーム送信メールからデータを取得してスプレッドシートに蓄積するツールの完全版](
https://tonari-it.com/gas-gmail-messageid/)
同じメールを転記しないようにするためのコードで参照しました。
[Google AppScript完全入門](https://amzn.to/3eeTPDG)の作者の高橋さんのブログ、
GASで分からないことがあってググったら、彼のブログはほぼ確実に出てくる。


[【GAS】正規表現を使ってGmailの本文から文章を抜き出す](http://www.initialsite.com/w01/13064)
本文中の文言を項目ごとに別のセルに転記したかったので、
メール本文の特定の文言を抽出するために、
正規表現についてはこの記事を参考にしました。

どこかの企業のブログですが、筆者が同じノンプログラマだったので、分かりやすかったです。



以上です。


このメールからシートへの転記の作業ですが、
社内でも私以外に似たような作業をしている人はいそうなので、手伝いにいきたいなと思います。
SoftEther VPNをPrometheusで監視する

# はじめに

[SoftEther VPN](https://ja.softether.org)はOSSのVPNソフトウェアです。これを[Prometheus](https://prometheus.io)で監視するためのプラグイン[softether_exporter](https://github.com/dalance/softether_exporter)をRustで実装しました。（商用ライセンスのPacketiX VPNでも使用可能です）

[Grafana](https://grafana.com)を使って以下のようなダッシュボードを作ったり、[Alertmanager](https://github.com/prometheus/alertmanager)で死活監視をしたりすることができます。
この記事ではsoftether_exporterのセットアップとダッシュボードの作成を簡単に解説します。
PrometheusやGrafana自体の設定には触れないので他の記事を参照してください。

![screenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84296/d551bb71-f3c7-69e9-5eb3-d045a9707418.png)

# softether_exporterのセットアップ

以下からバイナリをダウンロードして適当な場所（ここでは`/usr/local/bin`とします）に展開してください。

https://github.com/dalance/softether_exporter/releases

次にコンフィグファイル（場所は任意ですがここでは`/etc/prometheus/softether.toml`とします）を用意します。

```/etc/prometheus/softether.toml
vpncmd = "/usr/local/vpnserver/vpncmd"
server = "localhost:8888"

[[hubs]]
name = "HUB1"
password = "xxx"

[[hubs]]
name = "HUB2"
password = "xxx"
```

`vpncmd`はSoftEther VPNのサーバと一緒に配布されているコマンドラインツールで、そのバイナリへのパスを指定します。
`server`はSoftEther VPNサーバが動いているサーバとポートです（ここではsoftether_exporterと同じサーバで動いている想定です）。
さらに各仮想ハブ毎に名前とアクセスパスワードを設定します。

また、systemdを使ってサービスとして起動するのが便利なので以下のファイルを作ります。

```/etc/systemd/system/softether-exporter.service
[Unit]
Description=Prometheus SoftEther Exporter
After=network.target

[Service]
ExecStart=/usr/local/bin/softether_exporter --config.file=/etc/prometheus/softether.toml
User=nobody

[Install]
WantedBy=multi-user.target
```

systemdのリロードとサービス起動します。

```console
$ systemctl daemon-reload
$ systemctl enable softether-exporter
$ systemctl start softether-exporter
```

これでsoftether-exporterのセットアップは完了です。
適宜Prometheusサーバ側のスクレイピング設定を追加してください。

# ダッシュボード

冒頭のスクリーンショットにあるダッシュボードは以下で公開しています。
Grafanaの"Import dashboard"から以下のURLを入れてdata sourceの設定だけすればOKです。

https://grafana.com/grafana/dashboards/12053
CakePHPでSelect2を階層型のセレクトボックスで実現する方法【階層型】

## データベースの構成

■テーブル構成(placesテーブル)

|カラム|型|
| ---- | ---- |
|id|INT|
|parent_id|INT|
|name|VARCHAR|

■テーブルの中身

|id|parent_id|name|
| ---- | ---- | ---- |
|1|NULL|関東|
|2|1|東京都|
|3|1|埼玉県|
|4|1|栃木県|
|5|NULL|関西|
|6|5|大阪府|
|7|5|京都府|
|8|5|兵庫県|

「parent_idがnullが親」、[parent_idがnullでないものが子」です。

- 関東
    - 東京都
    - 埼玉県
    - 栃木県
- 関西
    - 大阪府
    - 京都府
    - 兵庫県

## コントローラでplacesテーブルから欲しい形で取得

下記のような形で$optinosに配列を定義したいです。

```php:PostsController.php

$optinos = [
    '関東' => [
        2 => '東京都',
        3 => '埼玉県',
        4 => '栃木県',
    ],
    '関西' => [
        6 => '大阪府',
        7 => '京都府',
        8 => '兵庫県',
    ]
];


```

Collectionクラスを使ってデータを取得します。

```php:PostsController.php

$parents = $this->Places->find()
    ->where([
        ['Places.parent_id is' => null]
    ]);

$places = $this->Places->find()
    ->join([
        'table' => $parents,
        'alias' => 'Parent',
        'type' => 'LEFT',
        'conditions' => 'Parent.Places__id = Places.parent_id'
    ])
    ->where([
            ['Places.parent_id is not' => null]
    ])
    ->select([
        'Places.id',
        'Places.parent_id',
        'Places.name',
        'Parent_name' => 'Parent.Places__name',
    ]);

$places = Collection($places);
$options = $places->combine('id', 'name', 'Parent_name')->toArray();

$this->set(compact('options'));

```

## ビューに渡す

コントローラで取得した```$options```をセレクトボックスの引数に渡します。

```php:add.ctp

$this->Form->select('id', $options, ['id' => 'select2'])

<script>
  $(document).ready(function() {
    $('#select2').select2();
  });
</script>
```

すると下記のようになります。

<img width="711" alt="スクリーンショット 2020-04-08 19.17.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264073/6cfb26cf-c0b4-8b3f-a639-3eac874727aa.png">



## 参考

[Select2公式サイト](https://select2.org/getting-started/basic-usage)
[CakePHP公式サイト](https://book.cakephp.org/3/ja/core-libraries/collections.html)
TextFieldをタップしたら日付のピッカーが出て欲しい

#テキストフィールドに年月日を入力したかった
テキストフィールドをタップすると普通はキーボードが出ますよね？
しかし今回はドラムロールというピッカーというか、そういうのが出て欲しかったんです。
ポンコツな私でも使える方法が合ったのでメモがてらここに書きます。

ポイントは
・日付を出すピッカーである「DatePicker」ってものが存在した

```swift:ViewController.swift
@IBOutlet weak var Appreciation: UITextField!

    let datePicker = UIDatePicker()

    override func viewDidLoad() {
        super.viewDidLoad()

        createDatePicker()
    }

   func createDatePicker(){
        
        // DatePickerModeをDate(日付)に設定
        datePicker.datePickerMode = .date

        // DatePickerを日本語化
        datePicker.locale = NSLocale(localeIdentifier: "ja_JP") as Locale

        // textFieldのinputViewにdatepickerを設定
        Appreciation.inputView = datePicker
        
        // UIToolbarを設定
        let toolbar = UIToolbar()
        toolbar.sizeToFit()
        
        // Doneボタンを設定(押下時doneClickedが起動)
        let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(doneClicked))
        
        // Doneボタンを追加
        toolbar.setItems([doneButton], animated: true)
        
        // FieldにToolbarを追加
        Appreciation.inputAccessoryView = toolbar
    }
    
    @objc func doneClicked(){
        let dateFormatter = DateFormatter()

        // 持ってくるデータのフォーマットを設定
        dateFormatter.dateStyle = .medium
        dateFormatter.timeStyle = .none
        dateFormatter.locale    = NSLocale(localeIdentifier: "ja_JP") as Locale!
        dateFormatter.dateStyle = DateFormatter.Style.medium

        // textFieldに選択した日付を代入
        Appreciation.text = dateFormatter.string(from: datePicker.date

        // キーボードを閉じる
        self.view.endEditing(true)
    }
```

新しいXcodeだとある程度エラーが出ますが、そこはFixで直しちゃいましょう！
群間のサイズの差の検定方法


http://gingi99.hatenablog.com/entry/2019/08/09/212415

を拝見した。こちらの記事は、Sample Ratio Mismatchの詳細についてわかりやすく解説がなされていた。

Sample Ratio Mismatchは以下のようなものだ。

> なぜこれが起こったかを調べたところ、実験開始後に、A/Bテストに割り当てられたTreatmentユーザ数がControlユーザ数と比べて有意に少なかったことが原因でした。それが起こってしまった原因を特定し（後に理由はでてきます）、正しく検証した結果、期待どおりのPositiveな差を検出することができました。
> まさにこの現象のこと、Sample Ratio Mismatch（SRM） と言います。つまり、A/Bテストのために割当したControl / Treatmentの2つの集団で、サンプルサイズが 期待どおりの比率で集まらなかった ことで、誤った結果を導いてしまう現象です。

「Control / Treatmentの2つの集団で、サンプルサイズが 期待どおりの比率で集まったかどうか」を検定したい。

この記事ではA/BテストのA群、B群が1:1になっていることを検定する方法について扱う。
検定方法は**「適合度検定」**である。

https://bellcurve.jp/statistics/course/9494.html

Pythonの`scipy`ライブラリ内の[`scipy.stats.chisquare`](https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.chisquare.html)を使うことで検定ができる。

例としてA/Bテストをしようとしていて、
A群が10000人のユーザー、B群が9900人のユーザーがいたとして、これが期待どおりの比率の1:1になっているかを検証する。

```python
import scipy
a_num = 10000
b_num = 9900
expect = (a_num + b_num)/2
observed_values=scipy.array([a_num, b_num])
expected_values=scipy.array([expect, expect])
scipy.stats.chisquare(observed_values, f_exp=expected_values)
```

これを実行すると `Power_divergenceResult(statistic=0.5025125628140703, pvalue=0.4783981994489356)`という結果を得られる。

統計量が`0.503`でp値が`0.47`。
有意水準を5%とすると、棄却できないため、A群とB群のサンプルには差がないと分かる。

試しに差がありそうなデータで実施してみる。

```python
a_num = 10000
b_num = 9000
expect = (a_num + b_num)/2
observed_values=scipy.array([a_num, b_num])
expected_values=scipy.array([expect, expect])
scipy.stats.chisquare(observed_values, f_exp=expected_values)
```

`Power_divergenceResult(statistic=52.63157894736842, pvalue=4.023672190684225e-13)`となり、p値が0.05未満であり、「差がある」つまりSRMが起こっていると言える。

## JavaScriptでやる場合

JSの統計ライブラリである[jstat](https://github.com/jstat/jstat)を利用する。

カイ二乗を算出し、分布表を参照する必要がある。

```javascript
const jStat = require('jstat');

const a = 10000
const b = 9000
const expected = (a+b)/2

const statistics = (a - expected)**2 / expected + (b - expected)**2 / expected
// 52.63157894736842

const df = 1
const pValue = 1 - jStat.chisquare.cdf(chi_2, df)
// 4.0234482412415673e-13
```

## 参考
オンラインのツール
https://www.gigacalculator.com/calculators/chi-square-calculator.php?test=goodnessoffit&data=15752+0.5%0D%0A15257+0.5

[Diagnosing Sample Ratio Mismatch in Online Controlled
Experiments: A Taxonomy and Rules of Thumb for Practitioners](https://exp-platform.com/Documents/2019_KDDFabijanGupchupFuptaOmhoverVermeerDmitriev.pdf)

いくつかの検定
https://toukei.link/programmingandsoftware/statistics_by_python/chisqtest_by_python/
簡易svn環境構築メモ

###前書き
2020年にSVN？
使っているところはまだありました。:frowning2:
あまり触ったことないので、
自分練習用の環境を作るときのメモです。

必ずしも、dockerを利用する必要はありません。
あくまで、ローカル環境を汚したくないので、dockerを利用しただけです。
コンテナー内の操作をそのまま、ホストマシンで実行してもいいです。

#### ホストマシンの操作
##### コンテナー作成
```
docker run -it --name svnServer \
-p 3690:3690 \
-v /home/vagrant/SvnRepository:/home/svn \
ubuntu 
```

#### コンテナー内の操作
##### アプリインストール
```
apt update
apt install -y subversion vim
```

##### リポジトリ作成
```
mkdir /home/svn/project
svnadmin create /home/svn/project
```

##### 設定ファイルの編集
下記の設定ファイルは全部`/home/svn/project/conf`にあります。

###### svnserve.conf

内容が多すぎるので、編集した内容のみを記述。

```
anon-access = none
auth-access = write
password-db = passwd
authz-db = authz
```

###### passwd
コメントアウトされた設定を反映するのみ。

```
harry = harryssecret
sally = sallyssecret
```

###### authz

コメントアウトされた設定を反映するのみ。

```
[aliases]
joe = /C=XZ/ST=Dessert/L=Snake City/O=Snake Oil, Ltd./OU=Research Institute/CN=Joe Average
[groups]
harry_and_sally = harry,sally
harry_sally_and_joe = harry,sally,&joe
[/]
harry = rw
&joe = r
* =
[repository:/]
@harry_and_sally = rw
* = r
```
##### svnserveを実行

```
svnserve -d -r /home/svn --log-file /home/svn/svnserve.log
```

#### 環境の使い方

SVNのURL: `svn://XXX.XXX.XXX.XXX/project`
SVNのユーザー: 上記 `passwd`を参照してください。(ユーザーID:パスワード)
サービス実行時のログ: `/home/svn/svnserve.log`
【Swift】TextFIeldがタップされた時に色を変えたい

#TextFieldが選択されたらボーダー色を変えたい
TextFIeldが選択された際にドロップシャドウがかかるように設定したかったのですが、知らなくて手こずったのでメモとして残しておきます。

ポイントとしては
・デリゲートで「TextFieldがタップされたよ〜」という通知を受け取る必要がある
・TextFieldがタップされた時やエンターボタンが押された時に使えるデリゲートメソッドがこの世にはもうある（知らなかった…）

```swift:filename.rb
// UITextFieldDelegateを継承する
class HogeViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet private weak var nameTextField: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // デリゲート
        nameTextField.delegate = self
    }
    
    // テキストフィールドをタップした際に呼び出されるデリゲートメソッド
    internal func textFieldDidBeginEditing(_ textField: UITextField) {
        // ドロップシャドウをかける
        textField.layer.shadowOpacity = 1.0
        textField.layer.shadowRadius = 4
        textField.layer.shadowColor = UIColor.blue.cgColor
        textField.layer.shadowOffset = CGSize(width: 0.0, height: 1.0)
    }
    
    // テキストフィールドの編集が終わった時に呼び出されるデリゲートメソッド
    internal func textFieldDidEndEditing(_ textField: UITextField) {
        // フォーカスが外れたら色を消す
        textField.layer.shadowColor = UIColor.clear.cgColor
    }

    // 画面をタッチするとキーボードが閉じる処理 
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.view.endEditing(true)
    }
}

```
結構省略したんでこれだと適用されないかも…？
とりあえずヒントになれば幸いです！
kotlinだとView情報の保存・リストアがParcelizeを使えるので簡単

`BaseSavedState` は `Parcelable` なので、 `@Parcelize` を使えば簡単に保存処理が書けます。以下は、 `num` というパラメータを保存する例です。

```kotlin
    override fun onSaveInstanceState(): Parcelable? {
        return SavedState(
                super.onSaveInstanceState(),
                this.num
        )
    }

    override fun onRestoreInstanceState(state: Parcelable?) {
        val savedState = state as? SavedState
        super.onRestoreInstanceState(savedState?.superState)
        savedState ?: return
        this.num = savedState.num
    }

    @Parcelize
    private data class SavedState(
            val superState: Parcelable?,
            val num: Int
    ) : BaseSavedState(superState)
```

簡単ですね
FragmentでBackボタンの処理をする

# どんな内容
FragmentでBackボタンの処理を変更する処理の書き方がネットで見つけたものがことごとくうまくいかなかったので、上手くいった方法のメモです。
androidx.activityのバージョンが関係してそうなので、今回のバージョンは

```
androidx.appcompat:appcompat:1.1.0
```

です。

# 参考にしたけどうまくいかなかっもの
@tarumzu さんの[「AndroidXでのバックキー制御」について、onBackPressedDispatcherの使い方や注意点補足](https://qiita.com/tarumzu/items/d6b18447ad24b5b5bfa2)を読んで、これで出来そうって思ったんですが、ちょっとうまくいかなかったです。

ダメだったのが、

```kotlin
addCallback(this, object : OnBackPressedCallback {
            override fun handleOnBackPressed(): Boolean {
~~ 略 ~~
```

の箇所
OnBackPressedCallbackに引数が必要みたい。
Booleanを返すメソッドが存在しないみたいだった。

# どうしたのか

```kotlin
.addCallback(this, object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
~~ 略 ~~
```
となった。

ただ、これだと、
>handleOnBackPressedでfalseを返す場合、 スタックに積まれたFlagment分すべて戻ってからActivityを終了させるといった動作になリます。
ただ、デフォルトの動作ではFragmentが載っていない、Activityのみのブランクページも表示されてしまうため、ブランクページを表示させたくない場合は別途下記のように書いてあげる必要があります。

が使えないので、

```kotlin
when {
    フラグとか -> {
        独自の処理
    }
    parentFragmentManager.backStackEntryCount > 0 -> {
        parentFragmentManager.popBackStack()
    }
    else -> {
        activity?.finish()
    }
}
```

としました。
とりあえず、想定どおり動いています。
ディレクトリ内の特定の名前のファイルをfindで指定してmvしたりcpしたりgzip化したりするコマンド（linux）

自分用メモ

ディレクトリ内の特定の名前のファイルにアプローチする．

カレントディレクトリ内のhogeという名前がついている.datファイルをすべてgzip化したければ,

```
find . -name "hoge*.dat" -exec gzip -v '{}' \;
```

hoge00.datを除いたhoge01.dat～hoge**.datをgzip化したければ，

```
find . -name "hoge*.dat" -not -name "*00*" -exec gzip -v '{}' \;
```


ちなみに移動をさせたければ，

```
find . -name "hoge*.dat" -not -name "*00*" -exec mv '{}' ディレクトリパス名  \;
```


応用しやすいね．

参考にしました↓
[findコマンドで複雑な検索条件を設定する](https://qiita.com/catfist/items/5504511fa5a028fc7c41)
Next.js + TypeScript プロジェクトに ESLint, Prettier を導入する

みなさんこんにちは。
今回は Next.js + TypeScript のプロジェクトに、ESLint と Prettier を導入してみましたのでそのメモを残します。

# 背景
久しぶりに開発業務で Next.js v9.3.0 と TypeScript v3.8.3 を使ったプロダクトを開発機会があり、改めてイチから環境を構築しました。

TypeScript の構文チェックには TSLint がありましたが、現在は deprecated になっているため ESLint を入れます。

Prettier は v2 がリリースされましたのでv2.0.2 とします。

[TSLint](https://github.com/palantir/tslint)

# ライブラリ
- "next": "9.3.0"
- "eslint": "^6.8.0"
- "@typescript-eslint/eslint-plugin": "^2.25.0"
- "@typescript-eslint/parser": "^2.25.0"
- "eslint-config-prettier": "^6.10.1"
- "eslint-plugin-prettier": "^3.1.2"
- "eslint-plugin-react": "^7.19.0"
- "prettier": "^2.0.2"

# ESLint

ここで下記のドキュメントを見てみましょう。

https://github.com/typescript-eslint/typescript-eslint/blob/master/docs/getting-started/linting/README.md

```
$ npm install -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
```
##### @typescript-eslint/parser
> This allows ESLint to understand TypeScript syntax.

ESLint が TypeScript の構文を理解します。

###### @typescript-eslint/eslint-plugin
> This allows you to use the rules within your codebase.

コード内でルールを使えるようにします。

```
$ npm install -D eslint-plugin-react
```
##### eslint-plugin-react
> React specific linting rules for ESLint

React 用 ESLint のプラグインです。

# Prettier
```
$ npm install -D prettier eslint-config-prettier eslint-plugin-prettier
```

##### eslint-config-prettier
> Turns off all rules that are unnecessary or might conflict with Prettier.

Prettier とコンフリクトしそうな、または、不必要なルールを off にできます。


##### eslint-plugin-prettier
> Runs Prettier as an ESLint rule and reports differences as individual ESLint issues.

Prettier をESLint のルールとして実行し、その差異を個々の ESLint の問題としてレポートします。


```javascript:.eslintrc.js
module.exports = {
  extends: [
    'eslint:recommended',
    'plugin:react/recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:@typescript-eslint/eslint-recommended',
    'plugin:prettier/recommended',
    'prettier/@typescript-eslint',
  ],
  plugins: ['@typescript-eslint', 'react'],
  parser: '@typescript-eslint/parser',
  env: {
    node: true,
    es6: true,
  },
  parserOptions: {
    sourceType: 'module',
    ecmaFeatures: {
      jsx: true,
    },
  },
  settings: {
    react: {
      version: 'detect',
    },
  }
}
```

# おわりに

私もすべての設定を把握しているわけではありませんが、これを機に色々調べてみようかと思います。
もっとプログラマ脳を鍛える数学パズル 感想文

# はじめに
アルゴリズムの勉強として、*[もっとプログラマ脳を鍛える数学パズル アルゴリズムが脳にしみ込む70問](https://www.amazon.co.jp/dp/B078LMFXXC)* を~~写経~~読んでいます。
70問目まで終わりましたので、その感想を投稿いたします。
# いいところ
アルゴリズムの説明がべったりとしておらず、（中級者以上の方は）サクサクと進められます。使用されているアルゴリズムは基本的なもの（二分探索、幅優先探索、順列組合せ、ユークリッドの互除法 等）です。

ソースの説明も最低限に抑えられており、下記のコードを見て、「ああ、インスタンスなハッシュね」とわかるレベルの人は、安心してお薦めできます。

```hash.rb
@memo = {}
```
Ruby 2.5.0 で動作を確認されているそうですが、手元の環境 (Ruby 2.7.0) でも正常に動作しました。
# 悪いところ
いいところの裏返しで、初心者の方は、分からないところを自身で調べながら進める必要があります。
しかし、同じようなクラスやメソッドが繰り返し出現しますので、調べる量としてはそれほど多くないものと思われます。

また、一文字変数として **W**(大文字) と **w**(小文字)、**i**(アイ) と **l**(エル) と **1**(イチ) が併用されており、初心者には辛いと思われます。
行き詰る前に、解答例をオフィシャルのHPからダウンロードし、それと自身の解答を *WinMerge や VSCode* で差分比較を行うことをお勧めいたします。
# まとめ
+ 一通り読んだ
+ ***Ruby*** で写経した
+ ***JavaScript*** はやってない

オフィシャルサイト
*[もっとプログラマ脳を鍛える数学パズル アルゴリズムが脳にしみ込む70問](https://www.shoeisha.co.jp/book/detail/9784798153612)*
ムーブセマンティクスってなに

本稿はコメントにて種々の誤りが指摘されています。コメントを参照してください。

---

恥ずかしながら、ムーブセマンティクスという言葉で初めてセマンティクスという言葉の意味を疑問に思いまして、調べました。タグにRustがありますが、便宜上つけただけです。詳しくはありません。



# 1.wikipediaを調べる
[英語版wikipedia](https://en.wikipedia.org/wiki/Semantics_(computer_science))にはこう書いてありました。

> In programming language theory, semantics is the field concerned with the rigorous mathematical study of the meaning of programming languages. It does so by evaluating the meaning of syntactically valid strings defined by a specific programming language, showing the computation involved. In such a case that the evaluation would be of syntactically invalid strings, the result would be non-computation. Semantics describes the processes a computer follows when executing a program in that specific language. This can be shown by describing the relationship between the input and output of a program, or an explanation of how the program will be executed on a certain platform, hence creating a model of computation.

DeepLさんに聞いてみましょう。

> プログラミング言語理論において、意味論はプログラミング言語の意味を厳密に数学的に研究する分野である。意味論は、特定のプログラミング言語で定義された構文的に有効な文字列の意味を評価し、それに伴う計算を示すことによって行う。このような評価が構文的に無効な文字列の評価である場合、その結果は非計算となる。**セマンティクスは、特定の言語でプログラムを実行する際にコンピュータがどのような処理を行うかを記述します。**これは、プログラムの入力と出力の関係を記述したり、特定のプラットフォーム上でプログラムがどのように実行されるかを説明したりすることで、計算のモデルを作成することで示すことができます。

意味論と言う意味があるようですね。

# 実践Rust入門を引いて調べてみると
wikipediaさんに聞いてもピンと来なかったので、入門書を引いて調べると、普通にわかりやすく書いてありました。



> “さてここでムーブは移動の意味ですが、セマンティクスはなんでしょうか？ これは意味論などと訳され、プログラミング言語ではソースコードがどういう意味を持つかを決めるルールを指します。これと対比される用語にシンタックス（syntax、構文）があります。こちらはソースコードをどう記述するかを決めるルールです。
要するにlet p2 = p1というシンタックスで書くと所有権がムーブするという意味になるのがムーブセマンティクスです。”抜粋:: κeen、河野達也、小松礼人  “実践Rust入門 ［言語仕様から開発手法まで］”

シンタックスとセマンティクスは対応する概念なんですね。

* コードをコンパイラがどう解釈するかという、**コード->意味**
という概念は**シンタックス**　コメントで指摘あり





* 人間がコード(コンパイラ)をどう設計して意味とコード(構文)を対応付けるか、**意味->コード**という概念が**セマンティクス**

## 追記(2020/04/08 20:11)
> シンタックスはコードが形式的に言語仕様に従って記述されているかどうかを表す概念 http://e-words.jp/w/シンタックス.html

コード->意味というよりもむしろコード->言語仕様のほうが近いようですね。
シンタックスエラーは構文の間違いという意味なのでそのほうが自然な解釈です。

上記の"コード->意味"といった表現は本質的な理解ではないことがコメントで指摘されています。
また、シンタックスとセマンティクスが二者択一のような概念というわけではないことが指摘されています。

# 結論
セマンティクスはソースコードの意味を決めること、あるいはその学問という意味合いで使われるようです。

## 追記2020/04/08 20:53
セマンティクスは意味論と訳します。
コードが表す意味(挙動)に注目する必要がある場合に使われます。

Rustにはムーブセマンティクスとコピーセマンティクスがあります。
ムーブセマンティクスとコピーセマンティクスは、所有権を移しスタック領域を解放する(move)か開放せずに別のスタック領域に値を複製する(copy)という点でセマンティクス(意味論)上、全く異なります。
しかし、シンタックス(構文)上は同じ(似ている)であるため、"セマンティクス"とつけて意味が異なることを強調します。

(以下はコメントで誤りを指摘されています。)
**ムーブセマンティクスは、スタック領域に確保されていたデータの所有権が移動することで、もともとの変数はスタック領域上では破棄されるなどの諸々の役割をこの構文に持たせるよという意味**だと私は理解しました。(違ったらご指摘ください。)


<del>しかし、それをムーブと組み合わせて"所有権を移動する式という意味"を持つ言葉として使うのはなにか大仰すぎるような気がします。ムーブだけと一般的過ぎるからかもしれません。</del>

# 参考文献
https://en.wikipedia.org/wiki/Semantics_(computer_science)
実践Rust入門 ［言語仕様から開発手法まで］
条件分岐 if

##環境,前提
Ruby 2.5.1
MacOS Mojave Ver.10.14.6

本記事はRubyがインストールされた前提の記事です。
Rubyをインストールしたあと、とにかくRubyをいろいろ触ってみて慣れていくための記事です。お役に立てば幸いです。


# ifとは

プログラミンングには必ず登場するif、
**「もし●●の時、◯◯を実行する」**というような形で
条件が適用されたら処理を実行し、条件に応じて処理を実行するプログラムです。



##ifの基本構造

```sample.rb
if 条件 then 
    処理   
end
```



「条件通りなら処理を実行する」そうでない場合は何もしません。
 **ifにはendがセットなのでend忘れには注意しましょう。**if の後の then は省略可能です。



##数値を比較する条件分岐


if文で数値を比較します。以下のコードはpower(変数)に100を代入してその値を比較しています。
if 条件部分の「>」は powerが99より大きい場合は条件が真になり処理が行われます。












```sample.rb
power = 100

if power > 99

puts "なかなかのパワーだ！！"

end

```
実行結果は以下のようになります。

```:Tarminai
なかなかのパワーだ！！
```
HugoとNetlifyで簡単なportfolio的なホームページ作成

## portfolioを作る
フロント未経験人間がHUGOとnetifyで作成したportfolioにすることを目指した，その際のログ。
git submoduleの使い方に詰まったので，[この記事](https://qiita.com/sotarok/items/0d525e568a6088f6f6bb)などを参考にした。
作ったページは[ここ](https://www.tsumar.com/)

### HUGOのインストール　
```bash
brew update
brew install HUGO
```

### HUGOの準備
まず，自分のportfolioを設置するディレクトリを作成し，`.git`を作成する。

```bash
hugo new site portfolio
cd portfolio
git init
git add .
git commit -m 'Initial commit'
```

### HUGOテーマのintroductionをsubmoduleとして導入

今回のportfolioにはHUGOの[introduction](https://themes.gohugo.io/hugo-theme-introduction/)テーマを用いた。
先ほど作成したportfolioディレクトリに上記のテーマのサブモジュールを追加する。
*(注釈)*
git submodule は、外部の git リポジトリを、自分の git リポジトリのサブディレクトリとして登録し、特定の commit を参照する仕組みです。
通常のレポジトリがブランチ単位で管理するのに対して，サブモジュールはCommitID単位で管理するというのが大きな違い。

```bash
sh
git submodule add https://github.com/TsumaR/hugo-theme-introduction.git themes/introduction
git submodule init
git submodule update
git submodule update —remote themes/introduction
```

```sh
git merge --allow-unrelated-histories origin/master
```
で強行突破

### configファイルの編集

```sh
cd ../../ #元のportfolioディレクトリに移動
cp ./themes/introduction/exampleSite/config.toml ./config.toml
```

言語設定を日本語に，contentDirの設定を`content`に変更する。

```sh
vim config.toml
git add config.toml
git commit -m "setting config file"
```

### 基本ファイルの作成　

とりあえず，骨格となる書類を追加していく。

```bash
hugo new home/index.md
hugo new blog/_index.md
hugo new work/_index.md
```

形式はsubmoduleした`themes/introduction/exampleSite`の中にあるファイルを参考にしてvimで編集した。

### ローカルでサイトの確認

```sh
hugo server
```

上記のコマンドにより，ポート1313のローカルサーバーが立ち上がる。ブラウザから`http://localhost:1313/`にアクセスして挙動を確認する。

### netlifyでの公開

次に作成したホームページを公開する。

```sh
hugo
```

でpublicディレクトリの作成。さらに，netlifyの公式[サイト](https://gohugo.io/hosting-and-deployment/hosting-on-netlify/)よりコピーした`netlify.toml`を[これらのサイト](https://qiita.com/jrfk/items/4c6df87ca72a76e30224)を参考にして修正。

## ここまででのエラー　

1. 写真が表示されない　
2. latest post，Read more，all postが表示されない。　

### 1. 写真が表示されないについて

SSL認証による可能性があるので，独自ドメインを取得して，HTTPS設定をした。
参考にしたのはこの[サイト](https://jamstack.jp/blog/how_to_set_custom_domain/)
Netlifyではwwwありドメインを強く推奨しているらしい。

結果的にHTTPSにしただけでは表示されなかった。結果的には，おそらく間違いが大量に存在した`config.toml`を修正して表示された。

### 2. blogページなどが正しい挙動を示さない

blogの文章がほとんど全て表示されてしまい，'Read more'や'All Post'ボタンも表示されないについて
前半の全て表示されてしまうについては，Hugoが文字数カウントをスペースで行っていることにより，日本語で記事を書いた際に，大量の文章が表示されてしまうことが原因だった。そのため，`config.toml`に

```
has CJKLanguage = ture
```

を書き加えることで解決した。

一方で，'Read more'のページが表示されていなかった。これらの問題はHugoのテーマにあるMultiple language対応のための設定を読み落としていることが原因だった。themesに日本語用の設定ファイルを追加してあげることで解決した。具体的には

```
themes/introduction/layouts/i18n/ja.toml
```

ファイルを`en.toml`をコピーする形で追加することで解決した。

[参考文献1](https://blog.tomoya.dev/2019/01/hugo-with-netlify/)
[参考文献2](https://r17n.page/2019/07/24/create-hexo-blog-process/)
Twilio Functionsを使って営業時間内だけ電話を転送する方法

 今回はTwilio Functionsを使って、営業時間内のみTwilioにかかってきた電話を任意の電話番号に転送する仕組みを実装します。

# 全体イメージ
<img width="941" alt="スクリーンショット 2020-04-08 17.30.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92989/db9d43c9-22ad-c547-6f68-cbddc07bc9de.png">

# 以下は取得済みとします
・Twilioアカウント
・Twilioの050番号

# 事前準備
[Twilio Functions を使って電話を転送する方法](https://www.tomokki-blog.com/2020/04/03/twilio-functions-%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E9%9B%BB%E8%A9%B1%E3%82%92%E8%BB%A2%E9%80%81%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/)を参考にTwilio Functionsを利用して電話を転送する仕組みを作ります。

# 営業時間のみ電話を転送する
以下コードをTwilio Functionsに貼り付けます。

```js
exports.handler = function(context, event, callback) {
    
    let twiml = new Twilio.twiml.VoiceResponse();
    var date = new Date();
    // JSTにするため9時間進める
    date.setHours(date.getHours() + 9);
    var currentHour = date.getHours();
    // 日：0、月：1、火：2、水：3、木：4、金：5、土：6
    var currentDay = date.getDay();
    // 営業時間が月曜日〜金曜日の10:00 - 18:00までの場合
    if(currentHour >= 18 || currentHour < 10 || currentDay === 0 || currentDay == 6 ){
        //業務時間外用TwiMLを出力する
        twiml.say({
            voice: 'alice',
            language: 'ja-JP' // 言語を設定しないと、日本語は読まれません。
        }, 'お電話いただきありがとうございます。大変申し訳ございませんが、ただいまの時間わ営業時間外となります。営業時間内に再度お掛け直しをお願いいたします。');
    } else {
        //  営業時間内
        twiml.dial({
            callerId: '+8150xxxxxxxx' // Twilioで取得した電話番号を設定します。ここで設定しないと転送時に非通知となってしまいます。
        },'+8190xxxxxxxx'); // 転送先の電話番号を設定します。
    }
	callback(null, twiml);
};
```

最後に、設定した電話番号に電話してテストしてみてください。
docker つかってサクッと c# を書きたい。

### 最終目標
- mono をいれて、c# をサクッと動作させたい。
- mono というものを知ったので使ってみたかった

#### 1.任意のフォルダを作成する
- c# のプログラムを置く場所を作成しておく。
- これ、準備したんだけど、うまく活用できてないので、今度 Dockerfile を作成して活用できるようにする。(次ね、次)

```console
% mkdir mono_project
% cd mono_project
```
#### 2.`docker`を使用して `mono`を取得する
- mono のイメージがない場合は、自動的に取得するので待つ。

```.console
mono_project % docker run -it mono /bin/bash
```

- 無事インストールしできたら、 mono の環境ができる。
- 環境ができたか、確認する。

```console
# もし、ログインしていない場合はログインしておく
mono_project % docker exec -it 作成したコンテナID /bin/bash
```

- mono の version を確認する

```console
root@:/# mono --version
Mono JIT compiler version 6.8.0.96 (tarball Wed Jan 15 10:18:35 UTC 2020)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
	TLS:           __thread
	SIGSEGV:       altstack
	Notifications: epoll
	Architecture:  amd64
	Disabled:      none
	Misc:          softdebug 
	Interpreter:   yes
	LLVM:          yes(610)
	Suspend:       hybrid
	GC:            sgen (concurrent by default)
root@:/# 
```
- パッケージ更新

```console
root@:/# apt update
```
- vim を入れておこうかな

```console
root@/# apt install vim
```

#### 3.c# をつくって実行してみる
- `test.cs` ファイルを作成し保存する。
- 今回は、さきに `test` というフォルダを作成し、その下でファイルを作成している

```c#:test.cs
using System
public class HelloWord
{
    static public void Main()
    {
        Console.WriteLine("Hello Mono Word")
    }
}
```
- 保存したら、コマンドラインからコンパイルする
- `mcs` コマンドでコンパイルが行える。

```console
root@:/test# mcs test.cs
```

- コンパイルされているか確認する
- `exe` ファイルができていればコンパイル完了。

```console
root@:/test# ls
test.cs  test.exe
```

- 実行してみる。
- `mono` コマンドで実行できる

```
root@:/test# mono test.exe
Hello Mono Word
```

やったー！出力したー(^_^)
Vue.js イベントハンドリングまとめ


## インラインメソッドハンドラ

簡単な処理であればインラインでメソッドを定義できる。

以下のコードは`button`要素にイベントハンドラ`v-on:click`を設定し、`button`をクリックするたびに`{{ count }}`の値が1増えていく。

```js:js
var app = new Vue({
  el: '#app',
  data: {
    count: 0 // countプロパティに0をセット
  }
})
```

```html:html
<div id="app">
  <p>
    {{ count }}
  </p>
  <button v-on:click="count++">
    Click!
  </button>
</div>
```

## メソッドイベントハンドラ

先ほどの同じ処理を`methods`オプションで定義してみる

`this.count`で`data`オプションに定義した`count`にアクセスできる

```js:js
var app = new Vue({
  el: '#app',
  data: {
    count: 0 // countプロパティに0をセット
  },
  methods: { // methodsオプション
    clickHandler() { // メソッドを定義
    this.count++
    }
  }
})
```


```html:html
<div id="app">
  <p>
    {{ count }}
  </p>
  <button v-on:click="clickHandler">
    Click!
  </button>
</div>
```

このように、テンプレート(HTML)とロジック(メソッド)は分けたほうがメンテナンス性が良くなる。

また、`v-on`は`@`に置き換える省略記法が用意されている

```html:html
<!-- <button v-on:click="clickHandler">と結果は同じ -->
<button @click="clickHandler">
    Click!
</button>
```


## イベントオブジェクト

メソッドの引数に`event`オブジェクトを渡すことによって取得できる

```js:js
methods: {
  clickHandler(event) {
  // 〜省略〜
  }
}
```

次のように、引数に渡すプロパティが存在する場合は、第一引数に`$event`を渡すことによって、`event`オブジェクトを取得できる

```html:html
<button v-on:click="clickHandler($event, message)">
  Click!
</button>
```

`Vueインスタンス`側にも記述する

```js:js
methods: {
  clickHandler($event, message) {
  // 〜省略〜
  }
}
```

## イベント修飾子

`.once`はイベントハンドラを1回だけ実行する

```html:html
<!-- 2回目以降はボタンを押しても何も起きない -->
<button v-on:click.once="method">click</button>
```

その他にもイベント処理を中断する`.prevent`など、様々なイベント修飾子が用意されている。
Chromeのfont-faceでlocalのフォントが読み込めない問題の解決方法 (Windows)

# ことのはじまり
[FontFace API](https://developer.mozilla.org/docs/Web/API/FontFace)というJavascriptからフォントを扱える草案段階のAPIを見つけて~~遊んでみたく~~勉強したくなり、ローカルにインストールされたフォントを読み込めるかどうかテストするツールを作成しました。
（ちなみにこちら https://semi65535.github.io/local-font-tester/ ）

ツールを使って~~遊んで~~テストしているとWindowsのChromeで特定のフォントだけどうやっても読み込まない。当然cssの`@font-face`でも読み込まれない。
FirefoxやMacのChromeでは表示されるのに。

このときはインストールしたはずの[M+フォント](https://mplus-fonts.osdn.jp/)がどうやっても読み込めませんでした。

```javascript
const font = new FontFace('mplus-2p-regular', 'local(mplus-2p-regular)');
font.load().then(() => {document.fonts.add(font)}); // WindowsのChromeでだけエラー
```

```css
@font-face {
  font-family: "mplus-2p-regular";
  src: local("mplus-2p-regular");
}
/* WindowsのChromeでだけ読み込まれない */
```

flagsの`#font-src-local-matching`をDisabledにして試してみましたが効果なし。

# 解決法
レジストリを眺めたりしているうちに、フォントファイルのインストール時に「すべてのユーザーに対してインストール」を行うとChromeからも認識可能になることを発見。
![fontinstall.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238976/4b465ad3-8a33-1e11-92e6-9326fbde7b10.jpeg)
一旦アンインストールしてから「すべてのユーザーに対してインストール」を行うと良いかもしれません。
ただの対症療法ですが同じことで悩んでいる人がいたら助けになれば幸いです。

ただしAdobe Fontsでアクティベートしたフォントなど、ユーザーがインストール作業を行わないフォントはこの方法は使えないので別の方法を考え中です。
どなたかご存知でしたら教えていただけると幸いです。

# 環境
Windows: Windows10 バージョン 1909 ビルド 18363.720
Chrome: 80.0.3987.163
C言語　ALDS1_5_B　Merge Sort

##問題
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_5_B&lang=ja

##コード
```c
#include <stdio.h>
#define MAX 500000
int count;

void print_array(int array[], int array_len)
{
    for (int i = 0; i < array_len; i++)
    {
        printf("%d", array[i]);
        if (i != array_len - 1)
            printf(" ");
    }
    printf("\n");
}

void merge_sort(int A[], int left, int right)
{
    int i, j, k, mid;
    int work[MAX];

    if (left < right)
    {
        mid = (left + right) / 2;
        merge_sort(A, left, mid);
        merge_sort(A, mid + 1, right);

        for (i = mid; i >= left; i--)
            work[i] = A[i];

        for (j = mid + 1; j <= right; j++)
            work[right - (j - (mid + 1))] = A[j];

        i = left;
        j = right;
        for (k = left; k <= right; k++)
        {
            count++;
            if (work[i] < work[j])
                A[k] = work[i++];
            else
                A[k] = work[j--];
        }
    }
}

int main(void)
{
    int N;
    int A[MAX];

    scanf("%d", &N);
    for (int i = 0; i < N; i++)
        scanf("%d", &A[i]);

    merge_sort(A, 0, N - 1);
    print_array(A, N);
    printf("%d\n", count);

    return 0;
}
```
##感想
- 両端からマージしていくやり方以外にもいろいろ書けるようなので、次回は別の書き方も挑戦してみる。
- メモリ使用量が4GBもあってたまげた。4GB超えるとデバッグできない。

2020/04/13　追記

- 両端からマージしないやり方に書き換えて見ようとしたけどうまく行かなかった。
- leftから進んで言って、midを超えた時、midにright側の最小値が入っているので、巻き込む。
- 両端から攻めていくと、leftがmidを越えようとしても、mid+1に最大値が入っているので、それがストッパーになる。よく出来ているわぁ。

2020/04/14　復習　所要時間２０分　ミスあり




##参考
C言語でマージソート - Qiita
https://qiita.com/omu58n/items/2aa3c751cfb10cdbbb43

Merge Sort Program in C - Tutorialspoint
https://www.tutorialspoint.com/data_structures_algorithms/merge_sort_program_in_c.htm
【VS Code】全角、末尾のスペース、TODO、校正など拡張機能Highlightが便利

VS Codeの拡張機能「[Highlight][]」をご存じでしょうか。
正規表現を利用して文字列を装飾する拡張機能なんですが、その自由度の高さから私にとっては手放すことのできない拡張機能となっています。

## ◆できること

- この拡張機能ひとつで、
  - 全角スペースの表示
  - 行末のスペースの表示
  - 文字間の2つ以上のスペースの表示
  - URLなど特定の文字列の装飾
  - 全角記号の装飾
  - 文書の曖昧な表現への装飾
  - TODOなどの指定した単語を含むコメント行への装飾
  - などなど

- 正規表現で表すことができれば、およそのことはできます。

## ◆できないこと

- リアルタイムに装飾されないことがあります。

## ◆設定例

設定は[Settings.json][]を直接、変更します。わたしの設定例をご紹介いたします。
作者さんの拡張機能[Highlight][]の紹介ページに、todoコメント行の設定例なども載っています。

※便利な設定をご存じの方、コメントで共有して頂けるとうれしいです。&#x1f60a;
　ご返信はできないかと思います。申し訳ありません。

  ```json:settings.json
     "(　)": [ // 全角スペース
      {
        "backgroundColor": "#FFC0F0",
        "borderColor": "#FF0086",
        "borderWidth": "1px",
        "borderStyle": "solid",
      }
    ],
    "( {1,})[\\r?\\n]": [ // 行末のスペース
      {
        "backgroundColor": "#FFC0F0",
        "borderColor": "#FF0086",
        "borderWidth": "1px",
        "borderStyle": "solid",
      }
    ],
    "(?<=\\S)( {2,})(?=\\S)": [ // 文字間の2個以上のスペース
      {
        "borderColor": "#FF0086",
        "borderWidth": "1px",
        "borderStyle": "none none dashed none",
      }
    ],
    "(https?|ftp)(:\/\/[-_.!~*\\'()a-zA-Z0-9;\/?:\\@&=+\\$,%#]+)": [ // URL
      {
        "color": "#FF7F00"
      },
      {
        "color": "#FF7F00"
      }
    ],
    "([！”＃＄％＆’（）＝～｜‘｛＋＊｝［］＜＞？＿－＾￥＠「；：」・])": [ // 全角記号
      {
        "borderColor": "#FF0086",
        "borderWidth": "1px",
        "borderStyle": "solid",
      }
    ],
    "(といった|という|こと|など|実際|なんて|のような|かもしれ|たったの|もある)": [ // あいまいな表現
      /* あいまいな表現の例
      だいぶ|すごく|たくさん|非常に|とても|もっと|かなり|たいそう|はなはだ|めっきり|極めて|ことのほか|いたく|こよなく|ずいぶん|大変|よほど|めっぽう|いやに|相当に|はるかに|大層|すぐに|ときどき|たまに|たまたま|しばらく|まあまあ|そこそこ|素晴らしい|素敵な|美しい|おいしい|かっこいい|つまらない|おもしろい|おかしい|優しい|偉い|危ない|新しい|古い|明るい|暗い|暑い|寒い|大きい|小さい|高い|安い|低い|長い|短い|早い|遅い|広い|狭い
      */
      {
        "backgroundColor": "rgba(255, 150, 200, 0.2)",
        "borderColor": "#FF0086",
        "borderWidth": "1px",
        "borderStyle": "none none dashed none",
      }
    ],
  },
  "highlight.maxMatches": 250,
  ```

## ◆VS Codeのテーマを作成しております

せっかくなので宣伝をいたします。
Visual Studio Code用のライトテーマ、[kindfeeling-light](https://marketplace.visualstudio.com/items?itemName=Aromatibus.kindfeeling)を作成させて頂いております。
完全にわたしの好みで作っているので好き嫌いはあると思います。
お時間頂けましたら、ぜひぜひお立ち寄りくださいませ。

[Highlight]: https://marketplace.visualstudio.com/items?itemName=fabiospampinato.vscode-highlight
[settings.json]: https://code.visualstudio.com/docs/getstarted/settings#_settings-file-locations
XSS SQLインジェクション

# 忘れがちなこと

- 出力側の対策と同じように入力側の対策も重要。
- 出力側の対策だけをしていると、サニタイズはできていても意図しない値が出力されてしまうことがある。
- 入力側の対策もしておけばフィルタリングに引っかかったら値を出力しない、ということもできる。

# Reflected XSS All Clients

- 入力側対策
    - 取得した値に対して無害化、値チェック、値のホワイトリスト管理をする
    - 以下のコードは**GETパラメータに「<」「>」が含まれなかったら**出力するという意味

```php
if(preg_match("/^[^\<\>]+$/", $_GET["keyword"]))｛
  echo $_GET["keyword"];
```

- 出力側対策
    - 出力時にサニタイズをする
        - PHPはhtmlspecialchars
        - JSはhtmlencoder.htmlEncode
    - 出力時にサニタイズする意味
        - 意図せぬところでデコードされる可能性がある
        - 二重エスケープを防ぐため

```php
echo htmlspecialchars( $_GET["keyword"], ENT_QUOTES, 'UTF-8');
```

# SQLインジェクション

- 入力側対策
    - 数字以外の場合は現在の年号に置き換える等

```php
if (isset($_GET['year']) && is_numeric($_GET['year'])){
    $selected_year = getList( $_GET['year'] );
else {
    $selected_year = getList( date("Y") );
}
```

- 出力側対策
    - GETパラメータをbindParam関数などで後からバインドさせる
    - そうすることでSQL文にとって特別な意味を持つ;やスペースがただの文字列として認識される

```php
$stmt->bindParam(':year',  $_GET['year'], PDO::PARAM_INT);
```