OmniAICreator/Qiita-1.07M huggingface dataset:
styleタグをjsから動的に書き換える

codepen的なもの
入力されたcssを即時反映する処理をjquery無しで書く

```javascript
const old = document.getElementById('inserted-style')
old && old.parentNode.removeChild(old)
const obj = document.createElement('style')
obj.setAttribute('id', 'inserted-style')
obj.appendChild(document.createTextNode(埋め込みたいcss))
document.getElementsByTagName('head')[0].appendChild(obj)
```
【10月開催】PwCテクノロジーコンサルタント1dayインターンシップ

#PwCテクノロジーコンサルタント1dayインターンシップ

##概要
PwCのテクノロジーコンサルタントになりきり、仮想クライアントに対しテクノロジーを駆使した課題解決の提案をしてもらうインターンシップです。

テーマは、デジタル戦略、サイバーセキュリティ戦略、データアナリティクス等、実際の仕事内容をリアルに再現したものとなっています。
チームでのコンサルティングワークには、現場で活躍する現役コンサルタントもメンバーとして加わり、コンサルタントの考え方、仕事の仕方を指導します。

ワーク後には、現役コンサルタントからの個別フィードバック、そしてチームメンバーや社員とフランクにお話いただける懇親会も予定しています。

ビジネスとテクノロジーの両方の知見を必要とするテクノロジーコンサルタントの仕事を体感してみませんか？

【こんな人にぜひ！】
- コンサルタントの仕事を体験してみたい人
- テクノロジーを用いたビジネスを考えることが好きな人　
- サイバーセキュリティに興味がある人
- データ分析に興味がある人
- 新しいアイデアを考えることが好きな人

##実施詳細
実施期間：2018年10月13日（土）
応募締切：2018年9月21日 （金）23:59
実施場所：PwCコンサルティング合同会社　東京丸の内オフィス（東京駅近辺）
募集人数：約50名
交通費：遠方から新幹線もしくは飛行機で参加される方には、弊社規定に従い、交通費をお支払いいたします。※国内のみ
昼食： 弊社でご用意いたします
参加資格：現時点で大学・大学院に在籍し、2020年3月卒業/修了見込みかつ2020年4月/10月入社が可能な方

##持ち物
筆記用具、時計、PC

##お問い合わせ
イベントに関するお問い合わせはkazuya.michiwa@pwc.comへお願いします。

##選考のフロー
■応募の流れ
選考フローは以下の通りです。 まずはマイページよりエントリーください。
マイページ作成（プレエントリー）
URLはこちら 
https://goo.gl/zE82CH
↓ 
エントリー 
↓ 
エントリーシート提出 
↓ 
Web適性試験（9月21日　 23:59 締切) 
↓ 
グループディスカッション（日時、会場はWeb適正検査を通過された方に個別にご連絡します）
↓
インターンシップ参加！
 

##ご注意
このイベントは、現時点で大学・大学院に在籍し、2020年3月卒業/修了見込みかつ2020年4月/10月入社が可能な方を対象としたイベントです。
スキーマ限定アカウントを試す（Oracle Database 18c）

Oracle Database はデータベース・インスタンスに接続するための「ユーザー」とテーブル等のオブジェクトをグループ化する「スキーマ」がほぼ同一の概念として定義されています。このため、オブジェクトをグループ化するスキーマを作成するためにはデータベース・ユーザーを作成する必要があります。
Oracle Database 18c ではデータベースの認証に使用できない「スキーマ限定アカウント」を作成することができるようになりました。

# スキーマ限定アカウントを作成
スキーマ限定アカウントは、CREATE USER 文または ALTER USER 文に NO AUTHENTICATION 句を指定します。認証を行わないため、同時に IDENTIFIED BY 句は使用できません。

```
SQL> CREATE USER schema1 NO AUTHENTICATION;

User created.

SQL> ALTER USER schema2 NO AUTHENTICATION;

User altered.

```

# アカウントロックとの違い
従来は、接続できないユーザーを作成する場合にはアカウントをロックする方法が取られました。ロックされたユーザーに対して接続を行う場合、「ORA-28000: The account is locked.」が発生しますが、スキーマ限定アカウントに接続する場合は「ORA-01017: invalid username/password; logon denied」が発生します。

```
SQL> ALTER USER schema2 IDENTIFIED BY schema2 ACCOUNT LOCK;

User altered.

SQL> CONNECT schema2/schema2
ERROR:
ORA-28000: The account is locked.

Warning: You are no longer connected to ORACLE.
SQL>
SQL> CONNECT schema1/schema1
ERROR:
ORA-01017: invalid username/password; logon denied

```

PROXY接続時の動作についても動きが異なります。下記ではスキーマ限定アカウントを作成し、代理認証が成功しています。本来の用途を考えると接続できないようにすべきではないかと思いますが、現状ではこのような仕様になっています。

```
SQL> CREATE USER real1 NO AUTHENTICATION;

User created.

SQL> GRANT CREATE SESSION TO real1;

Grant succeeded.

SQL> CREATE USER proxy1 IDENTIFIED BY proxy1;

User created.

SQL> ALTER USER real1 GRANT CONNECT THROUGH proxy1;

User altered.

SQL> CONNECT proxy1[real1]/proxy1;
Connected.

SQL> SELECT USER FROM DUAL;

USER
------------------------------
REAL1

```

一方でアカウントがロックされたユーザーの代理接続は失敗します。

```
SQL> ALTER USER real1 IDENTIFIED BY real1 ACCOUNT LOCK;

User altered.

SQL> CONNECT proxy1[real1]/proxy1;
ERROR:
ORA-28000: The account is locked.


Warning: You are no longer connected to ORACLE.

```

# 制約
[Oracle Databaseセキュリティ・ガイド](https://docs.oracle.com/cd/E96517_01/dbseg/configuring-authentication.html#GUID-54F53789-8FBD-436A-A301-23596803288D) にはスキーマ限定アカウントの制約として以下の記述があります。

>・スキーマ限定アカウントは管理者アカウントおよび非管理者アカウントの両方に使用できます。
>・スキーマ限定アカウントはデータベース・インスタンスでのみ作成され、Oracle Automatic Storage Management(ASM)環境では作成できません。
>・スキーマ限定アカウントにはシステム権限(CREATE ANY TABLEなど)や管理者ロール(DBAなど)を付与できます。スキーマ限定アカウントは、付与された権限を修正する必要があることを前提として、表またはプロシージャのようなオブジェクトを作成できます。
>・スキーマ限定アカウントにSYSDBA、SYSOPER、SYSBACKUP、SYSKM、SYSASM、SYSRAC、およびSYSDG管理権限を付与することはできません。
>・スキーマ限定アカウントは、単一セッション・プロキシのプロキシ認証でクライアント・ユーザーとして使用されるように構成できます。これは単一セッション・プロキシの場合、プロキシ・ユーザーの資格証明のみが検証され、クライアント・ユーザーの資格証明が検証されないためです。したがって、スキーマ限定アカウントがクライアント・ユーザーになることができます。ただし、2つのプロキシが存在するシナリオの場合はクライアントの資格証明を検証する必要があるため、スキーマ限定アカウントを構成することはできません。したがって、スキーマ限定アカウントの認証は失敗します。
>・スキーマ限定アカウントは、接続されたユーザー・リンク、固定ユーザー・リンク、または現行ユーザー・リンクのいずれかを使用してデータベース・リンク経由で接続することはできません。
docker コマンド 自分用メモ

# **docker コマンド チートシート**
> 全部ではない  
そのうち追記したいリスト
* ここに記述

# コンテナ・イメージ周り
## **ps**
**コンテナの確認**  

```sh
$ docker ps
```

> 調べたいコンテナが`running`の状態じゃないと見れない

***
## **images**
**イメージの確認**  

```sh
$ docker images
```

> 調べたいイメージを利用しているコンテナが`running`の状態じゃないと見れない

***
## **rm**
**コンテナの削除**  

```sh
# docker ps にて削除したいコンテナのIDを調べる
$ docker rm [コンテナのID]

# 止まっているコンテナ全削除したい場合はこれ
$ docker rm `docker ps -a -q`
```

***
## **rmi**
**イメージの削除**  

```sh
# docker images にて削除したいイメージのIDを調べる
$ docker rmi [イメージのID]

# イメージを全削除したい場合はこれ
$ docker rmi `docker images`
```
# Dockerhub系
## **pull**
Dockerhubからイメージをプルする。
> ぷるぷる、ぼくわるいイメージじゃないよ。

```sh
$ docker pull [リポジトリ名]
```

> リポジトリ名なんかに関しては**Docker store**とかで検索掛ければ出てくる(と思う)
fedora8 ネットワークトラブル

■ネットワークトラブル
急にpingが飛ばなくなったので、確認する
①traceroute(tracert)
②ipの設定
③route -nでデフォルトゲートウェイの設定

③でroute-nをするとデフォルトゲートウェイが表示されない。
「cat /etc/sysconfig/network」で確認すると
デフォルトゲートウェイは、表示される。
一度ネットワーク再起動を実施
「/etc/init.d/network restart」
再起動後、route -nで確認するとデフォルトゲートウェイが表示されるようになった。
自動起動設定いれてたんだどな。
GitLabでデフォルトブランチを変更する

初期設定ですとマージリクエストやブランチ作成時に、masterが選択されています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/267148/8f264906-b29c-99f5-4312-2d0f6338c9a4.png)

これだと、git-flowやGitHub flowに準拠した運用をしている際に、意図しないブランチ間でマージリクエストを出してしまったり、ベースブランチを間違ってしまったりと
本来development ブランチに対して行いたい操作を誤る可能性があります。

そのような場合には、デフォルト ブランチを変更することで防ぐことが出来ます。

# 変更手順

1.GitLabで設定を変更したいプロジェクトに移動し、ツリーからSettings->Generalを選ぶ。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/267148/d34d83e3-917e-bc98-c7f6-c5f526145588.png)

2.General project settings のExpandボタンをクリック。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/267148/25b8f3d3-1da0-a94d-5ead-b304bd537e3f.png)

3."Default Branch "をプルダウンメニューから変更し、"Save changes"をクリックして完了。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/267148/fcf511f7-941b-f5f6-eec9-82836adaf2ec.png)

# 注意
この設定はプロジェクト単位ですので、複数のプロジェクトに対して変更したい場合には、それぞれのプロジェクトで設定を変更してください。
spring のバージョン関係を見れるサイト(?)


# バージョン関係を調べるサイト(だと思う{英語読めない})

[バージョン関係参考サイト](https://docs.spring.io/spring/docs/4.3.18.RELEASE/spring-framework-reference/htmlsingle/#v4_3-Support-for-new-library-and-server-generations)

# pomに追加するバージョンを探すサイト
[Mavenの記述を探すサイト](http://mvnrepository.com/artifact/org.springframework/spring-web/4.3.11.RELEASE)
非IT業種のITメモ

　　非IT業でIT課題につかかる自分成長メモです。すべてを書く時間はないため、「先生」のみを1回／週ぐらいの頻度で挨拶(追記)するように頑張ります。
「先生」とは、よく使うコメント；トラブル対策；アルゴリズムの説明；自分の考え方を変えたもの。

##python使用時のトラブル
　　　１、[pipの再インストール](https://qiita.com/ousrok/items/6f87e33c1b444e4d86af)
　　　２、[import を楽になる](https://qiita.com/ousrok/items/24fd97831ac8a0301f0d)
　　　３、[Winpython 64bit のQt Designerを動かす](https://qiita.com/ousrok/items/9785d8b7a1faa78c5650)
　　　
##Python自習：
　　　[０、Pythonについて](https://qiita.com/ousrok/items/e7503363f6a800da584f)
　　　[１－１、Pythonのインストール](https://qiita.com/ousrok/items/ec10aee5dc9810831cba)
　　　[１－２、Pythonのインタプリタ](https://qiita.com/ousrok/items/0edacb92b0c7054ba81a)
　　　[２－１、初めてのpythonプログラム](https://qiita.com/ousrok/items/bf1aa75bc53d8b6e591a)
　　　[２－２、Python開発のエディタ](https://qiita.com/ousrok/items/baff667324fbc1ca01d5)
　　　[２－３、InputとOutput](https://qiita.com/ousrok/items/41fc2f951cdd90a53c5a)
　　　[３－１、pythonの基礎](https://qiita.com/ousrok/items/871ddad90a4e71397a1f)
　　　[３－２、Pythonのデータ型、数値と変数](https://qiita.com/ousrok/items/a672f1263e61fc80d8b0)
　　　[３－３、Pythonの文字列と文字コード](https://qiita.com/ousrok/items/1cec71e5cd029cf442d1)
　　　[４、和、平均、中央値、最頻値、分散、標準偏差計算](https://qiita.com/JunJun0706/items/9d1befb90a823c466c32)
　　　[５、イテレータ](https://qiita.co４m/ousrok/items/66cfbc64c555dd0847db)
　　　[６、python ファイル操作関係まとめ](https://qiita.com/ousrok/items/21d7da8f5d2dff860f88)


##OpenCV関係
　　　[１、画像の読み込み、表示、保存、サイズ取得、図形書く](https://qiita.com/ousrok/items/d81038877024eb80d133)


以上
さくらのクラウドのアーカイブを高速にダウンロード＆アップロードする方法

# アーカイブのゾーン間コピーができない!?
北海道で発生した地震の影響で停電が発生し、現在さくらインターネットの石狩データセンターでは、自家発電装置で給電が行われています。しかし燃料が切れるのは時間の問題です。停止を避けるために石狩ゾーンから東京ゾーンにサーバーを移動しようとしている人も多いと思いますが、混雑しているのか、ゾーン間でのアーカイブのコピーでエラーが発生しています。
（※この記事は復旧していない事を前提に書いてます）

そこでさくらが提供しているアーカイブのゾーン間コピーの機能を使わずに、FTPSを使って転送する方法を考えてみました。

# アーカイブのゾーン間コピーの流れ
石狩：アーカイブを作成
　↓
どこか：アーカイブを石狩からダウンロード
　↓
どこか：アーカイブを東京へアップロード
　↓
東京：アーカイブからディスクを作成
　↓
東京：サーバーに接続

# ネットが遅いときは？
アーカイブはFTPSでダウンロード/アップロードができますが、プロバイダーの回線経由で何百GBものアーカイブをダウンロードするのは非常に困難です。そこで、さくらのクラウド内に、「ファイル置き場」とするサーバーを立てます。私はCentOS 7で行いました。（6だとlftpがうまくいかなかった）

さくらのクラウドはネットワークが標準では100Mbpsですが、スイッチ＋ルーターを追加することで100Mbps〜3000Mbpsまで選べます。お値段も結構しますので、ファイルを転送するときだけ1000Mpbsにする、みたいな感じですかね。

最初にスイッチを作成して、ルーターを有効にします。
次にファイル置き場となるサーバーを作成し、NICの接続先をこのスイッチにします。これで高速にダウンロード/アップロードができるようになりました。

# アーカイブのダウンロード
ファイルはSFTPで転送しますので、curlやlftpを使います。私はcurlでやりました。

```
設定ファイル .lftprc
set ftp:ssl-auth TLS
set ftp:ssl-force true
set ftp:ssl-allow yes
set ftp:ssl-protect-list yes
set ftp:ssl-protect-data yes
set ftp:ssl-protect-fxp yes
set ssl:verify-certificate no
```

```download.sh
#!/bin/bash
DLFILE=archive.img
echo "Download from Sakura archive"
echo -n "Host name? " ; read SERVER
echo -n "User name? " ; read USER
echo -n "Password? "  ; read PASS
curl -u $USER:$PASS --ftp-ssl --ftp-pasv -k --compressed \
  ftp://$SERVER:21/$DLFILE -o $DLFILE
```

# アーカイブのアップロード
curlでやると途中で止まってしまうので、lftpを使いました。

```
$ lftp
> open ホスト -p 21 -u ユーザー名
Password: 
> put archive.img
``` 

この方法で試したところ、50〜70MB/sで転送できました。
さすがに速いですね！

ちなみにcurlでアップロードするスクリプトはこんな感じです。（なぜか途中で止まる）

```upload.sh
#!/bin/bash
UPFILE=archive.img
echo "Upload to Sakura archive"
echo -n "Host name? " ; read SERVER
echo -n "User name? " ; read USER
echo -n "Password? "  ; read PASS
curl -u $USER:$PASS --ftp-ssl --ftp-pasv -k --compressed \
  -T $UPFILE ftp://$SERVER:21/
```
０、Pythonについて

##背景
"Guido van Rossum"さんは1989年のクリスマス前後に暇つぶしでpythonを作りました。

　現在、全世界で約600種類のプログラム言語があり、流行っているのは約20種類前後です。もしTIOBEプログラミングランキングをご存知であれば、各言語の人気度が分かると思います。下図は最近10年間の良く使われるプログラミング言語の変化図です。
![0_2018_TIOBE.png](https://qiita-image-store.s3.amazonaws.com/0/263439/7bf4eee6-6b32-36e0-728e-c99df4669ad8.png)


　各プログラミング言語には独自な特性があります。例えば、計算速度を追求し、ハードの性能を十分に発揮するにはC言語が良く使われます。
　ソフトを開発するとき、全てのコードを自分で書くよりも既存のモジュール等を利用すると開発速度が大幅に早まります。例えば、emailのクライアントを作るために全て自分で開発した場合、1年間、2年間以上かかります。普通の開発は既存ライブラリ等を利用し、STMTPモジュール、GUIモジュール等を利用して2週間程度で開発出来ます。

　Pythonは標準モジュール以外、世界中の開発者がネット、ファイル、GUI、データベース等大量なモジュールを提供しています。「batteries included」と言われています。自分で書く必要はなく、直接使えば良いです。もちろん、自分で書いたモジュールを他人に提供することも出来ます。
　多くの大手ホームページはPythonで作成されています。例えば、YouTube,Instagram,Google,Yahoo,NaSAでPythonが使われています。

##Pythonはどんな開発を向いているか？
　まず、ネットワーク関係です、ホームページ、サーバサービス等。
　次は、一般事務用のツール等。管理システムのスクリプト開発等。

##Pythonのデメリットは？
　1番は計算速度が遅いです。C言語と比べると、実行時は一行づつCPUに分かる言語に翻訳しているので、相当な時間がかかります。C言語は実行する前に、既にCPUに分かる言語に翻訳(コンパイルと言う)しているので早いです。しかし、普通のタスクでは、そこまでの計算速度は必要ないです。例えば、emailの処理ソフトで、C言語は0.001秒、Pythonは0.1秒、100倍の差ですが、ネット等の通信で１秒ぐらいかかるかもしれません。そうなると、1.001秒と1.1秒の差はホントに重要でしょうか？ その計算速度の差は無視できるでしょう。
　2番はソースコードは暗号化できないため、秘密性がありません。C言語はコンパイルして、Windows用のXXX.exeファイルとして配布できます。コンパイルされたXXX.exeファイルからソースコードに戻すのは不可能です。Pythonは、ソースコードのままで配布されるので秘密性はありません。幸い、単純なソフトを売る時代がもうすぐなくなります。新しい商業モデルは、ネットワークを通じてサービスを販売する時代が流行します。しかも、オップンソースの発展もどんどん進んでいます。ソースコードを公開しない会社は殆どソースコードの価値は高くなく、公開すると商品になりません。
　
##Pythonは何ですか？
Pythonはプログラム開発用言語。世の中にプログラム開発用言語は沢山あります。例えば、非常に難しいC言語、流行っているJava、初心者向けのBasic、Web開発のJavaScript等。

　まず、プログラムの基本知識を言います。全てのプログラム開発は、PCに仕事をさせる目的です。例えば、文書を書く、ネットでショッピング等、ただPCはCPUに分かる「言語」しか対応できない。なので、全てのプログラム開発言語は、CPUに分かる「言語」に翻訳する必要がある。そこで、同じ仕事をPCにさせるため、違い開発言語の書くコード数は違います、大きな差があります。
　例えば、同じタスクを実現する為、C言語は1000行のコードが必要、Javaは100行でできる、Pythonはただ20行で出来るかもしれません。
　ですので、Pythonは相当な高級言語となります。
　なんでコード行数が少なくで出来るの？計算速度を犠牲したためです。C言語は1秒で、Javaは2秒、Pythonは10秒必要かもしれません。
　そうすると、開発言語は高級になるほど、簡単になりますか？普通に言えば、そうです。ただ、非常に抽象的な計算の中に、高級なPythonでも非常に難しいです。高級≠簡単となります。
　しかし、初心者と普通なタスクに対して、Pythonは非常に簡単で使いやすい言語です。Googleでも非常に幅広く使われているので、できたら使える場面はない等の心配は必要ありません。

##Pythonで何ができるの？
　普通の日常タスク(ファイルのミラーリング、アラーム設定等)、ホームページ作成(YouTube等)、ネットゲーム等、いろいろできます。
　Pythonの出来ない事も当然あります。OSの作成はC言語しかできない；スマーホappはSwift/Objective-C（iPhone）とJava（Android）等しかできる；３DゲームなどはC或いはC++の方が良いかもしれません。

目次　[非IT業種のITメモ](https://qiita.com/ousrok/items/135734b5f66afb497253)

参考：[廖雪峰的官方网站](https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000)、「初めてのPython 第3版」
Laravel Factory Relation Fakerの復習 

Laravelのバージョンを色々使ってると細かい所で、このバージョンの時は出来て、このバージョンのときは出来ないみたいな状況になるので、思った所を復習して置こうと思います。

今回は、テストコードを書く時に不可欠なfactory系でrelationのfactoryを使用時です。

まず、<a target="_blank" href="https://laravel.com/docs/5.1/testing#model-factories">Model Factories</a> が入ったのは、バージョン5.1からになります。

良くあるサンプルで、ブログとコメントのfactory例を上げてみます。

```php
$factory->define(App\Post::class, function ($faker) {
    return [
        'title' => $faker->sentence,
        'body' => $faker->sentence
    ];
});
$factory->define(App\Comment::class, function ($faker) {
    return [
        'post_id' => factory(App\Post::class)->create()->id,
        'body' => $faker->sentence,
    ];
});
```

v5.1.2では、上記のfactory定義を行い、`post_id` をパラメーターで渡したとしても、元々Factoryで定義してあるModelも作られる現象が発生します。
その問題はこちらで述べています：https://github.com/laravel/framework/issues/9245

```php
Factory::create(App\Comment::class, [
    'post_id' => $someGivenPostId
]);
```

その後 https://github.com/laravel/framework/pull/9387 のPull Reqestで5.1.3にマージされて、以下の形式で対応可能になりました。

```php
// v5.1.3以降に$attributesが追加
$factory->define(App\Comment::class, function ($faker, $attributes) {

    $post_id = isset($attributes['post_id']) ? $attributes['post_id']: factory(App\Post::class)->create()->id;

    return [
        'post_id' => $post_id, 
        'body' => $faker->sentence,
    ];
});
```

しかし、上記だと複雑なRelationに対応出来たいとの事で https://github.com/laravel/framework/pull/12231/ のpull reqestでLaravel v5.2.2 で最終的な現在（書いてる時点でv5.7です)の形になってます。

```php
//　v5.2.16以降Clousreでrelationを定義
$factory->define(App\Post::class, function (Faker $faker) {
    return [
        'post_id' => function() {
            return factory(App\Post::class)->create()->id;
        },
        'body' => $faker->sentence,
    ];
});
```

これで以下の方法でも、余計なデーターが作られない様になりました。

```php
factory(App\Comment::class, 10)->create(['post_id' => App\Post::find(1)]);
```

v5.1.3で追加された、`$attribites` もそのまま残されていますので、必要に応じて$attributesを元に分岐しても大丈夫です。
Visual Basic Editor の見た目をどうにかする (フォントと色の変更と行番号表示)

以前 [Windows 版の Eclipse の外観を手っ取り早くカスタマイズ](https://qiita.com/ynakayama/items/205327301322e8b6835e)する方法を書きましたが、今度は Windows 版の VBE (Visual Basic Editor) の外観を手っ取り早くカスタマイズする必要が出てきたのでメモ。

VBE は Eclipse よりもさらにカスタマイズができなさそうなので、まず Emacs っぽいキーバインドについては諦めます。

## フォントおよび表示色のカスタマイズ

デフォルトで見た目が白背景な上にフォントが MS なんとかフォントで見づらいので、これをいじります。

メニューの [ツール] - [オプション] から エディターの設定タブを開きます。

編集する箇所は標準コードのフォントおよび前景背景色と、コメント、キーワード、識別子のみ。あとはデフォルトで OK です。

![1.png](https://qiita-image-store.s3.amazonaws.com/0/38501/d625525a-4775-713a-d63a-402fa254813f.png)
![2.png](https://qiita-image-store.s3.amazonaws.com/0/38501/bd1bdb54-b349-3134-0f66-21393c3ec3c4.png)
![3.png](https://qiita-image-store.s3.amazonaws.com/0/38501/e63d4e5b-2348-1318-9a3c-ea20e76926a2.png)
![4.png](https://qiita-image-store.s3.amazonaws.com/0/38501/a3a0af2e-88ed-4c38-7210-6078d1dccc1c.png)

フォントについては Eclipse のときと同じく [MeiryoKe_Console を利用](http://www.sukicomi.net/2012/11/meiryo-console.html)。

## 行番号の表示

少し長いモジュールだと行番号の表示が欲しくなります。

これはデフォルトで用意されていない (!) ので、アドオンを使います。

[OfficeVBA(64bit)環境VBE用アドイン AddLineNumbers VB6/VBA for x64 Version 1.41](http://mtj-k.no.coocan.jp/software/office_vb6/addlinenumbers_vba_x64.html)

なお 32bit の場合は[こちら](http://mtj-k.no.coocan.jp/software/office_vb6/addlinenumbers_vb6.html)。

付属のドキュメントにも書いてありますが、ダウンロードして管理者権限で以下のようにコマンドを打てばインストールできます。

```
regsvr32 VB6IDEAddLineNumbersAddin.dll
```

アンインストールする場合は以下の通り。

```
regsvr32 VB6IDEAddLineNumbersAddin.dll /u
```

## 完成

![5.png](https://qiita-image-store.s3.amazonaws.com/0/38501/ca764dbe-4f72-da85-90b8-f478c3b9d86b.png)

不満を言えば色々ありますが、ひとまず見た目だけでもどうにかなりました。
【Laravel】On-Demand Notifications をモック化してテストする


## 先に結論

次のようにしてできる。

```php
use Illuminate\Notifications\AnonymousNotifiable;

Notification::fake();

// :
// テスト対象のロジック実行
// :

Notification::assertSentTo(
    new AnonymousNotifiable(),
    InvoicePaid::class, // 対象の Notification class
    function($notification, $channels, $notifiable) {
        return $notifiable->routes['mail'] == 'test@example.com';
    }
);
```

## 前提1：On-Demand Notifications とは？

メール送信のような「通知」を行う際には通常、 `Illuminate\Notifications\Notifiable` trait を `use` した class に対して `notify()` メソッドを実行する。

On-Demand Notifications はそのような class が存在しない対象に対して、直接通知を行うための仕組みである。

* 公式ドキュメント
    * https://laravel.com/docs/5.6/notifications#on-demand-notifications

```php
Notification::route('mail', 'taylor@example.com')
            ->route('nexmo', '5555555555')
            ->notify(new InvoicePaid($invoice));
```

例えば私は、「フォームにメールアドレスだけ入力してもらって、アカウント登録フォームの URL をそのメールアドレスに送信する」という場面で使っている。[^1]

## 前提2：Notifications をモック化してテスト

テストを実行では、実際にメール送信等はしたくない。
そこで、Laravel では Notifications をモック化する仕組みを提供している。

* 公式ドキュメント
    * https://laravel.com/docs/5.6/mocking#notification-fake

```php
Notification::fake();

// Perform order shipping...

Notification::assertSentTo(
    $user,
    OrderShipped::class,
    function ($notification, $channels) use ($order) {
        return $notification->order->id === $order->id;
    }
);
```

このモック化のおかげで、実際にメールを送信することなく「対象にメールが送信されること」を確かめるテストを書くことができる。


## 本題：On-Demand Notifications をモック化してテスト

しかし、公式ドキュメントの情報からだけでは On-Demand Notifications を使っている場合にモック化する方法がわからない。

```php
Notification::fake();

// こんな風にしていい感じに解釈してくれないかな、と期待したが
Notification::assertSentTo(
    'test@exmaple.com',
    InvoicePaid::class
);
```

```bash
# こんなエラーで怒られる
ErrorException: get_class() expects parameter 1 to be object, string given

/var/www/app/vendor/laravel/framework/src/Illuminate/Support/Testing/Fakes/NotificationFake.php:165
/var/www/app/vendor/laravel/framework/src/Illuminate/Support/Testing/Fakes/NotificationFake.php:153
/var/www/app/vendor/laravel/framework/src/Illuminate/Support/Testing/Fakes/NotificationFake.php:129
/var/www/app/vendor/laravel/framework/src/Illuminate/Support/Testing/Fakes/NotificationFake.php:43
/var/www/app/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php:221
:（以下略）
```

実は解決方法は Laravel5.5 の時点で既に提示されており、

https://github.com/laravel/framework/pull/21379


```php:再掲
use Illuminate\Notifications\AnonymousNotifiable;

Notification::fake();

// :
// テスト対象のロジック実行
// :

Notification::assertSentTo(
    new AnonymousNotifiable(),
    InvoicePaid::class, // 対象の Notification class
    function($notification, $channels, $notifiable) {
        return $notifiable->routes['mail'] == 'test@example.com';
    }
);
```

のようにすることで、めでたくモック化してテストできる。

## 余談：`AnonymousNotifiable` とは？

On-Demand Notifications を利用するときに出てくる Notifialbe な class こそが `AnonymousNotifiable` 。

```php:tinker
>>> \Notification::route('mail', 'test@example.com')
=> Illuminate\Notifications\AnonymousNotifiable {
     +routes: [
       "mail" => "test@example.com",
     ],
   }
```

[^1]: ちなみに、Laravel 5.7 よりその機能自体が提供されたよう（https://laravel.com/docs/5.7/releases#laravel-5.7）
Docker Swarmを構築して、docker-compose.ymlを読み込ませてみる

# Docker Composeって？

Docker Composeは、複数のコンテナを立ち上げるときのネットワーク、依存関係、環境変数などを、yamlファイルに記述して、コマンド一つで起動できるツールです。
Docker runするときの引数をgitで管理できるようになります。

例として、公式ドキュメントにあるredisのdocker-compose.ymlが以下になります。

```yaml:docker-compose.yml
version: '3'
services:
  web:
    build: .
    ports:
     - "5000:5000"
    volumes:
     - .:/code
  redis:
    image: "redis:alpine"
```

この例では、ymlが置いてあるのと同じディレクトリにある`Dockerfile`をビルドし、webという名前をつけてコンテナを起動します。
ポートはホストの5000/tcpと接続され、カレントディレクトリにあるファイルはすべてコンテナの/codeと動悸されるようになります。

また、`redis:alpine`イメージを使ってredisのコンテナも起動させています。

# Docker Swarmって？

Docker Swarmは、k8sやrancherなどと同じ、複数のマシン間でDockerコンテナをいい感じに管理してくれるツールです。Openstackは仮想マシンを扱いますが、簡単に言えばそのコンテナ版です。

複数の物理マシン（もちろん仮想マシンでも可）に、Swarmのノードを起動させると、どれか一つのマシンが親となって、他のノードにコンテナの起動を割り振ります。

また、Swarmノードが死んでそこで動いてるコンテナと疎通できなくなった場合、他の生きてるノードで同じコンテナをデプロイする機能なども備えています。

# 今回やりたいこと

- Docker Swarmクラスタを構築する
- docker-compose.ymlをswarmに読み込ませて、docker-compose.yml内のサービスを別々のマシンで動くようにする

# Docker Swarmクラスタの構築

DockerのSwarm Modeで起動させます。

何らかの方法で、sshアクセスやコンソールアクセスできるLinuxマシンを3台ほど用意します。
また、事前に最新バージョンのDockerをインストールしておいてください。

そして、そのうち一つをマネージャノードにします。
残りの２つはワーカーノードにします。
名前の通り、前者が管理ノード、後者が実際にコンテナが起動するノードです。

## マネージャノードの作成

マネージャノードにさせたいマシンで以下を実行します。

```shell
$ docker swarm init --listen-addr=0.0.0.0:2377
```

マシンに複数のIPアドレスがある場合（NICが複数ある場合）に、`--advertise-addr 192.168.1.10:2377`などが必要になります。そのマシンに割り当てられているIPアドレスを指定してください。

## ワーカノードの作成

`docker swarm init`したときに、`docker swarm join --token SWMTKN-hoge 192.168.x.x`のようにコマンドが表示されます。
そのコマンドを、そのままワーカノードにしたいマシンで実行してください。自動でマネージャノードに接続しにいきます。

以上でDocker Swarmの構築は完了です。

この状態で`docker info`を実行すると、以下のように表示されます。

```
Swarm: active                                                                                                                                                                                                        
 NodeID: jltk9n4dj0hujknbpgxibcr5u                                                                                                                                                                                   
 Is Manager: true
 ClusterID: p1dekrd6ip80zuauc9s75fb5f
 Managers: 1
 Nodes: 3
 Orchestration:
  Task History Retention Limit: 5
 Raft:
  Snapshot Interval: 10000
  Number of Old Snapshots to Retain: 0
  Heartbeat Tick: 1
  Election Tick: 10
 Dispatcher:
  Heartbeat Period: 5 seconds
 CA Configuration:
  Expiry Duration: 3 months
  Force Rotate: 0
 Autolock Managers: false
 Root Rotation In Progress: false
 Node Address: 192.168.1.3
 Manager Addresses:
  192.168.1.3:2377
```

# Docker-compose.ymlを読み込ませる

docker swarm modeにdocker composeのファイルを読み込ませるには、docker stackコマンドを使います。

```shell
$ docker stack deploy myapp -c docker-compose.yml
```

docker overrideなどを使って複数docker-compose.ymlを指定したい場合、-cオプションを複数回使えます。


そして、各サービス（コンテナ）が立ち上げっているか確認しましょう。

```shell
$ docker stack services myapp
ID                  NAME                    MODE                REPLICAS            IMAGE                PORTS
…
```

ここでREPLICASが1/1になっていれば成功です。

# 動いてるかどうか試してみる

マネージャノードに割り当てられているIPアドレスに対して、リクエストを送ります
※マネージャノードの中から127.0.0.1向けにアクセスしても反応しないので注意

```
$ curl 192.168.1.3
```
iOS11.3.1 ズーム機能が画面の上半分しか機能しない時にした事

僕は視力が良くないので小さい文字などを見るときはよくズーム機能を使います。

ホントによく使うので3本指でダブルタップすると起動するように設定してます。


# 半分だけ？
このズーム機能が**iOS11.3.1**にしてから時々おかしくなります。

**スマート入力モード**をオンにして**ソフトキーボード**を表示した時のように画面の上半分しか機能しなくなります。

この状態になると**ソフトキーボード**が表示されてなくても上半分しかズームしないのですが、スクロールすればいいと思い3本指でスワイプしても下半分にスクロールできません。

こうなってしまうとホントの虫眼鏡を使うか、**スクリーンショット**を撮って**写真アプリ**で拡大して見るしかありません。

# 対処方法
+ ~~iOSを最新にする。~~
    + iOSを最新にすれば良いのかも知れませんが、それができない事情の人も少なくないと思います。

+ ~~再起動する。~~
    + できることなら再起動もしたくありません。 

+ リスプリング
    + たったこれだけでなおりました。


# リスプリング
ホーム画面やドックのアイコン操作に反応したりステータスバーの表示を管理してるのが**SpringBoard**というアプリです。
この**SpringBoard**を**Restart**する事を**ReSpring**と言うそうです。


**方法**
+ [iOSデバイスの定番ファイラー。“Filza File Manager” - Qiita](https://qiita.com/maboy/items/9966fdbd49a9329cdc11)
iOS SkyWaySDKでビデオ通話　音声出力先変更

##SkyWayを使用してビデオ通話するiOSアプリ
音声の出力が通話用スピーカーだったのを内蔵スピーカーに変更しました。

**`AVFoundation`をインポートして
remoteAudioSpeakerを定義**

```
    func remoteAudioSpeaker() {
        self.remoteStream?.setEnableAudioTrack(0, enable: true)
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            // speaker
            do {
                try AVAudioSession.sharedInstance().setActive(true)
                try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord)
                try AVAudioSession.sharedInstance().overrideOutputAudioPort(AVAudioSessionPortOverride.speaker)
                self.remoteStream?.setEnableAudioTrack(0, enable: true)
            } catch {
                print("AVAudioSessionCategoryPlayAndRecord error")
            }
        }
    }
```

**イベントストリームでremoteAudioSpeakerを呼び出し**

```
        mediaConnection.on(SKWMediaConnectionEventEnum.MEDIACONNECTION_EVENT_STREAM, callback: { (obj) -> Void in
            self.remoteAudioSpeaker()
            if let msStream = obj as? SKWMediaStream{
                self.remoteStream = msStream
            }
        })
```

###注意点
STREAMのなかに直接書くのではなく、外部に書いて1秒遅れで出力先を設定すべし
vs2010でmanaged directx その16

#概要
c#で、3Dやりたかった。
shadertoyのコードを移植してみた。

#写真

![image](https://qiita-image-store.s3.amazonaws.com/0/18104/2ba38f82-b81d-be80-6a12-7c32b5e4daa1.png)


#サンプルコード

```
#define PI			3.14159265359
#define TWOPI		6.28318530718
struct VS_IN {
	float4 Pos: POSITION;
	float4 color: COLOR;
};
struct VS_OUT {
	float4 Pos: POSITION;
	float4 color: COLOR;
	float2 coord: TEXCOORD;
};
VS_OUT VSmain(VS_IN In)
{
	VS_OUT output = (VS_OUT) 0;
	output.Pos = In.Pos;
	output.color = In.color;
	output.coord = In.Pos.xy;
	return output;
}
float linearstep(float edge0, float edge1, float x)
{
	float t = (x - edge0) / (edge1 - edge0);
	return clamp(t, 0.0, 1.0);
}
float smootherstep(float edge0, float edge1, float x)
{
	float t = (x - edge0) / (edge1 - edge0);
	float t1 = t * t * t * (t * (t * 6. - 15.) + 10.);
	return clamp(t1, 0.0, 1.0);
}
void plot(float2 r, float y, float lineThickness, float3 color, inout float3 pixel)
{
	if (abs(y - r.y) < lineThickness) pixel = color;
}
float4 PSmain(VS_OUT In): COLOR
{
	float2 r = In.coord;
	float3 bgCol = float3(1.0, 1.0, 1.0);
	float3 axesCol = float3(0.0, 0.0, 1.0);
	float3 gridCol = float3(0.5, 0.5, 0.5);
	float3 col1 = float3(0.841, 0.582, 0.594);
	float3 col2 = float3(0.884, 0.850, 0.648);
	float3 col3 = float3(0.348, 0.555, 0.641);
	float3 pixel = bgCol;
	const float tickWidth = 0.1;
	float x = r.x;
	float y = r.y;
	if (abs(sin(PI * r.x) - y) < 0.02) pixel = col1;
	if (abs(0.25 * linearstep(-0.5, 0.5, x) + 0.1 - y) < 0.01) pixel = col3;
	if (abs(0.25 * smootherstep(-0.5, 0.5, x) - 0.9 - y) < 0.01) pixel = col3;
	plot(r, 0.5 * clamp(sin(TWOPI * x), 0.0, 1.0) - 0.7, 0.015, col2, pixel);
	plot(r, 0.6 * exp(-10.0 * (x + 0.8) * (x + 0.8)) - 0.1, 0.015, col2, pixel);
	return float4(pixel, 1.0);
}

technique MyTechnique
{
	pass MyPass
	{
		VertexShader = compile vs_2_0 VSmain();
		PixelShader = compile ps_2_0 PSmain();
	}
}


```


以上。
VS Code 1.27 の新機能 - 設定画面のGUI変更

https://code.visualstudio.com/updates/v1_27#_settings-editor

今まで独特のインターフェースだった設定画面のGUIがようやく変更された。ここ最近のリリースではプレビュー機能として実装されていたので試用はできていたが、今回晴れてデフォルトのGUIとして実装された。

v1.26|v1.27
---|---
![setting_old.PNG](https://qiita-image-store.s3.amazonaws.com/0/181011/6287dc4f-e079-9c64-433d-1210f1978327.png)|![settings.PNG](https://qiita-image-store.s3.amazonaws.com/0/181011/1f69663e-b7a6-b01d-a8c6-637609223e66.png)

従来のGUIの場合は左側にデフォルトの設定、右側にユーザー設定（というかjsonファイルそのもの）が表示されていたが、新しいGUIの場合は一般的な設定画面の形式に変更になっている。

設定を変更すると項目の左側に細い縦棒のインジケーターが付く。設定をデフォルト値に戻したい場合は項目の歯車アイコンをクリックし、`設定をリセット`を選択する。うん、一般的だ！

![setting_set_reset.gif](https://qiita-image-store.s3.amazonaws.com/0/181011/071823ff-c9d4-e561-2ea9-bdcd4f575103.gif)

変更された項目のみを表示したい場合は、右端の`...`メニューから`変更した設定を表示`を選択すると変更された設定のみ表示される。あるいは検索条件入力フィールドに`@modified`と入力する。

![setting_modified.jpg](https://qiita-image-store.s3.amazonaws.com/0/181011/e48aa7a5-4c0f-1c9f-baeb-6f39526f6002.jpeg)




なお、従来のGUIを使用したい場合は、コマンド`基本設定: 設定(JSON)を開く`を実行するか、設定画面右端の`...`メニューから`settings.jsonを開く`を選択する。
docker-machine 自分用のメモ

# **docker-machine コマンド チートシート**
## docker-machineとは？
dockerコンテナを動かすためのホスト環境を構築するためのツール。  
> 中身のことをboot2dockerと呼んだりする。
  
> 全部ではない  
そのうち追記したいリスト
* **scp**

> [マシン名]は指定なしだと`default`となる。  

# マシンの作成・削除・アップデート

## **create**
**Dockerマシンを作成する**  

```sh
$ docker-machine create --driver virtualbox [マシン名]
```  
> --driver  
> ドライバを指定するオプション。`virtualbox`がおすすめ。


***
## **rm**
**Dockerマシンを削除する**  

```sh
$ docker-machine rm [マシン名]
# 失敗例
machine does not exist, assuming it has been removed already
# 成功例
Successfully removed dev
```

***
## **update**
**Dockerの最新バージョンにマシンをアップデート**  

```sh
$ docker-machine update [マシン名]
```

***
***
# マシンの利用
## **start**
**起動**  

```sh
$ docker-machine start [マシン名]
```

***
## **restart**
**再起動**  

```sh
$ docker-machine restart [マシン名]
```

***
## **stop**
**停止**  

```sh
$ docker-machine stop [マシン名]
```

***
## **kill**
**強制終了**  

```sh
$ docker-machine kill [マシン名]
```
> 強制終了は極力使わず、特別な事象でもない限り`stopコマンド`で穏便に終了させる。  
> (stopコマンドが効かない。とか。)

***
## **ssh**
**マシンに接続する**  

```sh
$ docker-machine ssh [マシン名]
                        ##         .
                  ## ## ##        ==
               ## ## ## ## ##    ===
           /"""""""""""""""""\___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ /  ===- ~~~
           \______ o           __/
             \    \         __/
              \____\_______/
 _                 _   ____     _            _
| |__   ___   ___ | |_|___ \ __| | ___   ___| | _____ _ __
| '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__|
| |_) | (_) | (_) | |_ / __/ (_| | (_) | (__|   <  __/ |
|_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_|
```
> お決まりの憎いクジラ  
> 抜けたい場合は`exit`

***
***
# マシンのステータス確認
## **status**
**マシン状態の確認**  

```sh
$ docker-machine status [マシン名]
```

***
## **ls**
**Dockerホストの一覧を表示する**  

```sh
$ docker-machine ls
NAME      ACTIVE   DRIVER       STATE     URL   SWARM   DOCKER    ERRORS
default   -        virtualbox   Stopped                 Unknown
```
> 上記はdefaultという名前のマシンが停止している状態の例

***
## **ip**
**マシンのIPアドレスを調べる**  

```sh
$ docker-machine ip [マシン名]
```

***
## **env**
**マシンの環境変数を確認**  

```sh
$ docker-machine env [マシン名]

# windows
$ docker-machine env [マシン名] --shell 'cmd'
```

> ホストマシンのDocker Remote API のエンドポイントや、certファイルのパスが確認できる。

***
## **config**
**マシンの起動設定の確認**  

```sh
$ docker-machine config [マシン名]
```
Android Stutioで Installing APK のまま進まない


開発中にエミュレーターでアプリを実行しようとしたところ、`Installing APK` のままapkがインストールされないという現象が発生しました。
Android StudioやエミュレータやOS自体の再起動をしてみましたが解決しません。

adbでapkをインストールしようとすると以下のエラーが発生していました。

```
adb: failed to install app-mock-debug.apk: Failure [INSTALL_FAILED_CONTAINER_ERROR: Failed to extract native libraries, res=-18]
```

[ここ](https://stackoverflow.com/questions/12480302/failure-install-failed-container-error-when-trying-to-install-android-apk-pack)からストレージサイズを大きくすれば良さそうだと思い、エミュレータのInternal Storageのサイズを大きくしたところ無事にインストールできるようになりました。
XcodeとGitHubの接続

個人の備忘録として記録しています

#手順
##(1) GitHubへの登録、リポジトリの作成
別のサイトに譲ります。

##(2) X code projectの作成
プロジェクトを作成するときにチェック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/26564/ca3390a3-0f62-e718-e87e-f989f94c1950.png)


##(3) Xcodeの設定
###(3)-1
Xcode左上の「Navigator」の左から２つめを選ぶ
![image.png](https://qiita-image-store.s3.amazonaws.com/0/26564/0b177d1e-766c-fb00-b7ae-9c7ddb0772e1.png)
##(3)-2
「Remote」を「controlボタン」押しながらクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/26564/8268667a-c9de-cb4f-29b1-e6a186a853c5.png)
##(3)-3
「Create ・・・・・　Remote on GitHub」を選ぶ
![image.png](https://qiita-image-store.s3.amazonaws.com/0/26564/c1e7344a-a26f-5d08-b2a1-57a238c80e29.png)

##(3)-4

これで使えるはずです。
Sphinxの表をExcelで管理する

なんだかんだいって、Excelで管理することになるのが世の習わしです。
Excelで管理されたデータを他で使うために、CSVにすることが多いと思います。
CSVにすると、Sphinxの表がつくれます。

# ExcelをCSVに変換する

Excel CSV I/Oアドインというとても便利なアドインがあります。
http://fnya.cocolog-nifty.com/blog/2012/03/excel-csv-io-ex.html

自動化ではありませんが、どのExcelファイルでも使えるという利点があります。
使い方は、開いたExcelファイルで、Excel CSV I/Oのエクスポートボタンを押すだけです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/44912/95233d95-707e-dc8d-1799-dca8ec913f73.png)

ダイアログが出てきますが、基本、そのままエクスポートです。

# Sphinxの表をCSVで扱う

Sphinxでは表のデータをCSVファイルから取り込むことができます。
そこで、こんなふうに、Excelファイル, CSVファイル, .rstファイルを置いておけば、Excelファイルを変更して、Excel CSV I/OでCSVエクスポートするだけで、Sphinxの表を更新できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/44912/22e633a4-77bb-cc6e-8cf0-c79073b1961a.png)

.rstファイルでCSVファイルを指定する方法は、例えばこんな感じです。

```
ワーディング
===========

ワーディング一覧
---------------

.. csv-table::
   :file: wording.csv
   :encoding: sjis
   :header-rows: 1
````

残念ながら、SphinxでMarkdownできるようになるcommonmarkでは、この仕組みが機能しないようなので、.mdファイルではできません。

# おまけ1: CSVをいろいろ変換する

csvkitというツールが便利です。
https://github.com/wireservice/csvkit

例えば、CSVからJSONに変換したいときには次でOKです。

```
csvjson data.csv > data.json
```

# おまけ2: 改行が含まれたExcelを扱う

CLEAN関数を使うと、不要な情報（というか変換の邪魔になる情報）を削除できます。
エクスポート用のシートを作成しておいて、そこの全部のセルを元のデータがあるシートを参照してCLEANをかませておけば、元のデータを変更するだけで、クリーンなCSVファイルが手に入ります。

```
=CLEAN(訪問分担!C3)
```
C#のDateTimeのKindについて

サマータイムなんてやめてほしいけど、ちょっと気になるので調べてみたら、C#のDateTimeにKindというプロパティがあることに今更ながら気がついた。

[DateTime::Kind プロパティ](https://msdn.microsoft.com/ja-jp/library/system.datetime.kind%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396)
DateTimeKind 列挙型で、

| メンバー名   |内容|
|:------------|:------------|
| Local       | ローカル時刻 |
| Utc         | UTC         |
| Unspecified | 不明        |

のいずれかの値を持つ。
初期値は、Unspecified

```c#:DateTime.Kind
DateTime datetime1 = new DateTime(2018, 1, 1, 0, 0, 0);
DateTime datetime2 = new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Local);
DateTime datetime3 = new DateTime(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc);
Console.WriteLine(datetime1.Kind.ToString());
Console.WriteLine(datetime2.Kind.ToString());
Console.WriteLine(datetime3.Kind.ToString());
Console.WriteLine(datetime1.ToString("yyyy-MM-dd HH:mm:ss K"));
Console.WriteLine(datetime2.ToString("yyyy-MM-dd HH:mm:ss K"));
Console.WriteLine(datetime3.ToString("yyyy-MM-dd HH:mm:ss K"));
```
この結果は、

``` :Result
Unspecified
Local
Utc
2018-01-01 00:00:00
2018-01-01 00:00:00 +09:00
2018-01-01 00:00:00 Z
```
となる。
ここで、`datetime2`と`datetime3`でTimeSpanを出したらどうなるのかな？

```c#:TimeSpan
Console.WriteLine((datetime2-datetime3).TotalHours.ToString());
Console.WriteLine(datetime2 == datetime3);
```
この結果は、

``` :Result
0
True
```
となる。
TimeSpanや比較ではDateTimeのKindは関係なしということなのかな。

じゃ、DateTimeのKindってどういう使い方をするのか？
[DateTimeが表す日時が現地時刻かUTCかを設定する](https://dobon.net/vb/dotnet/system/newdatetime.html#kind)
>Kindプロパティの値によって違いが出るのは、DateTimeを別のタイムゾーンの日時に変換する時です。DateTimeの計算や比較には影響を与えません。

とあるので、ひとつのタイムゾーンのみを考えればいいような場合は気にしなくてもいいのかな。
まぁ、それでもKindはLocalにしておくのが良さそうな気はする。


.NET2.0 SP1からDateTimeOffsetという型が追加になっているみたいで、UTC+オフセット時間を持っているらしい。
こっちのほうがサマータイムでは有効なのかな？とも思ったけど、
[DateTimeの代わりにDateTimeOffsetを使用する](https://dobon.net/vb/dotnet/system/datetimeoffset.html)
> ただし、DateTimeOffsetはUTCとの時差を保持しているだけで、タイムゾーンの情報は持っていませんので、サマータイムのように特定の時期だけ時差が変わってしまうケースにまでは対応していません。

とあるので、例えばOSのアップデートでサマータイム対応されたとしてもDateTimeOffsetではダメということかな。

前に、[データベースの`TIMESTAMP WITH TIME ZONE`型を値をC#でやり取りするときにはDateTimeOffsetを使うんじゃないのかな？](https://qiita.com/kkino90h/items/147aed6162c82a1022f9)と思って確認したときも、`TIMESTAMP WITH TIME ZONE`型も`TIMESTAMP WITHOUT TIME ZONE`型もDateTime型で扱うということだったけど、じゃそのときのDateTimeのKindはそれぞれどうなっていたのか？これは確認する必要がありそう。
DeepCut: Joint Subset Partition and labeling for Multi Person Pose Estimation を読んだ

Leonid Pishchulin, Eldar Insafutidinov, Siyu Tang, Bjoern Andres, Mykhaylo Andriluka, Peter Gehler, and Bernet Schiele
CVPR2016
・[arXiv](https://arxiv.org/abs/1511.06645),[PDF](https://arxiv.org/pdf/1511.06645.pdf)

#1.どんなもの？
複数人が重なり合っている時でもに姿勢推定を行うために、重なり合う部分を分割しラベル付けする手法を提案
つまり、人々が重なっているような場合にうまく推定することを目指す


#2.先行研究との違いは？
従来手法ではまず人々を検出し、その後姿勢を推定していたため複数人に対しての姿勢推定が難しかった。(2015年)

この論文の手法では以下の手順で推定を行う。

(a)初期検出。この時点では全ての部位候補を検出。
(b)同じ色の部分グラフが一人の人物にクラスタリングされ、各々の部分はその部分クラスに対応してラベル付けされる。（異なる色および記号は異なる部位に対応する）
(C)推定結果。

<img width="654" alt="スクリーンショット 2018-09-07 12.49.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/262587/3c0ed432-efa3-6575-3fcb-32b9e06ee8ac.png">


以下がこの手法の特徴である。
(1)部位の予測をリンクさせることで人数を予測できるため人数が不明でも対応可能。
(2)部位候補の初期集合において部位予測を非アクティブ化またはマージすることを可能にし非最大抑制(NMS)を効果的に行う。
(3)NP困難な問題を線形整数問題へキャストする。

#3.技術や手法のキモはどこにあるか？
強力な部分検出器
　・改良したFast R-CNNを利用(Adapted FR-CNN,AFR-CNN)
　　ーDetection proposals
　　ーLarger context
　　 
　・Dense Architecture (Dense-CNN)
　　VGGに基づいた構造
　　ーStrideを調整（8pxに減らす）
　　ーScaleを調整（340pxに）
　　ーLoss functionを調整
　　　出力と交差エントロピーの損失に対する活性化関数としてシグモイド関数を利用
　　ーLocation refinement
　　ーRegression to other parts　　
　　ーTraining

　・DeepCutモデル
   モデルによって生成されたセット全体から代表的な検出を選択することでNP困難にならないように工夫


#4.有効性の検証
トレーニングと検証に用いたデータセット
“Leeds Sports Poses” (LSP) 
“LSP Extended” (LSPET)
“MPII Human Pose” (“Single Person”)

##部分検出器の性能評価
LSPにおけるAFR-CNNの評価
<img width="403" alt="スクリーンショット 2018-09-07 9.05.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/262587/c2bd1d68-e3ef-8bf2-b186-f0c56695f33e.png">

LSPにおける畳み込み構造の評価
<img width="399" alt="スクリーンショット 2018-09-07 9.09.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/262587/7fc72f40-7c4c-2b5c-0022-3c68fa54f934.png">

<img width="397" alt="スクリーンショット 2018-09-07 9.24.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/262587/2df51ab2-4500-366f-5440-520bb6b7050c.png">

##DeepCutの結果
#一人分の姿勢推定
LSPへの結果
<img width="406" alt="スクリーンショット 2018-09-07 9.26.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/262587/3b708bef-160c-9e09-d6d2-4ec42091565d.png">

MPIIへの結果
<img width="405" alt="スクリーンショット 2018-09-07 9.27.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/262587/93e61cfb-c953-cb40-92a7-100be21ad703.png">

#複数人への姿勢推定
WAFへの結果
<img width="354" alt="スクリーンショット 2018-09-07 9.29.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/262587/d317372a-0ca1-0bd4-93c0-0558b00218c9.png">

MPII Multi-Personへの結果
<img width="404" alt="スクリーンショット 2018-09-07 9.30.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/262587/cc41840c-7f25-58ce-d502-a16e90da06e4.png">


<img width="846" alt="スクリーンショット 2018-09-07 9.13.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/262587/2276287a-fb7d-ecc1-4f2f-1af2934c2971.png">

複数人への姿勢推定において特に提案手法は良い結果
上の画像のように従来手法では、人々が重なり合うと推定結果で別人の部位とつながったりする

#5.議論はあるか

#6.次に読むべき論文はあるか
今回の論文に続く内容
DeeperCut:  A Deeper, Stronger, and Faster Multi-Person Pose Estimation Model, ECCV2016
・[arXiv](https://arxiv.org/abs/1605.03170)
【Mac用】1行でScala環境構築

# 1行でScala環境構築

- install sbt

```bash

$ brew install sbt@1
```

- sbtの起動確認

```bash
$ sbt
[info] Loading project definition from /Users/[ユーザ名]/project
[info] Set current project to [ユーザ名] (in build file:/Users/[ユーザ名]/)
[info] sbt server started at local:///Users/[ユーザ名]/.sbt/1.0/server/973b5ad03bae2162f3bf/sock
sbt:[ユーザ名]>

```

# 参考資料
- [sbt Reference Manual — Installing sbt](https://www.scala-sbt.org/1.x/docs/Setup.html)
【Python】Seleniumでページ全体のスクリーンショット撮るならマルチプロセスで！


# はじめに
Seleniumでページ全体のスクリーンショットを撮る際，以下のようなプログラムをよく目にしますが，複数のページを撮りたい場合にはあまりふさわしくないように感じます。

```py
driver.get(url)
w = driver.execute_script('return document.body.scrollWidth')
h = driver.execute_script('return document.body.scrollHeight')
driver.set_window_size(w, h)
driver.save_screenshot('screenshot.png')
```

### 上記手法の問題点

- **別のページにアクセスする前にサイズをリセットする必要がある。**
ページによっては画面のサイズやアスペクト比で表示形式を変えている場合があります。PC用（スマホ用）デザインで統一したい場合はでいちいちウィンドウサイズをリセットする必要があります。

- **動作が遅い**
基本的にSeliniumの動作は遅いです。そのため複数のページに対して一連の作業を順にやらせていてはかなりの時間がかかってしまいます。


これら問題から，複数ページのスクリーンショットを取る場合はマルチプロセスで行うことをおすすめします！



# コード
以下のプログラムは[GitHub](https://github.com/derodero24/Deropy/blob/master/scraping.py)でも見ることができます。

```py
import subprocess

def screenShotFull(driver, filename, timeout=30):
    '''フルページ スクリーンショット'''
    # url取得
    url = driver.current_url
    # ページサイズ取得
    w = driver.execute_script("return document.body.scrollWidth;")
    h = driver.execute_script("return document.body.scrollHeight;")
    # コマンド作成
    cmd = 'gtimeout ' + str(timeout)  \
        + ' "/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary"' \
        + ' --headless' \
        + ' --hide-scrollbars' \
        + ' --incognito' \
        + ' --screenshot=' + filename + '.png' \
        + ' --window-size=' + str(w) + ',' + str(h) \
        + ' ' + url
    # コマンド実行
    subprocess.Popen(cmd, shell=True,
                     stdout=subprocess.PIPE,
                     stderr=subprocess.STDOUT)
```

# 解説
大まかな流れはコメントを読めば分かると思いますが，少しだけ補足させていただきます。

**コマンドオプション**

- `gtimeout`：プロセスの時間制限を設定。ページにアクセスできないなど，何らかの理由で処理が進まない場合にプロセスが残り続けてしまうことを防ぎます。インストールは`brew install coreutils`で。LinuxやWindowsの場合は`timeout`だったかな？
- `headless`：ヘッドレス指定
- `hide-scrollbars`：スクロールバーを隠す
- `incognito`：シークレットモード。拡張機能がオフになったり，履歴が残らなくなる。
- `screenshot`：スクリーンショット
- `window-size`：ウィンドウサイズ指定。


ちなみにFirefoxを使用したい場合は，コマンドを以下のように変更すればOK。
Firefoxの場合はサイズ指定をしなくてもいいので少し簡単です。（ただしPC用デザインでしか取得できなくなる。）取得率があまり高くないようなので，私はChromeで取得できなかったときだけ使用するようにしています。

```py
cmd = 'gtimeout ' + str(timeout)  \
    + ' "/Applications/Firefox Developer Edition.app/Contents/MacOS/firefox"' \
    + ' -headless' \
    + ' -private' \
    + ' -screenshot=' + filename + '.png' \
    + ' ' + url
```
`-private`：プライベートモード（Chromeでいうシークレットモード）



# 使用例
```py
driver.get(url)
screenShotFull(driver, filename='screenshot')
driver.close()
```
MacOSにNodeインストールでハマったポイント

# はじめに
Mac初心者がNode.js入れる際に試行錯誤したときのメモなので中級者の方は閲覧注意 :sweat_drops:

# 確認
Reactを使うためNode.jsをMacにインストールすることになったので、とりあえず確認。

```
$ node -v
v4.5.0
```
ファッQ?いやいや、入れてないし、、しかも古い。
ちなみにMac環境はOS X Yosemite 10.10.5（これも古くてすいません。。。 :bow: ）

# 削除
とりあえず消します。
<img width="249" alt="qiita_up.png" src="https://qiita-image-store.s3.amazonaws.com/0/61433/66b25cb6-79f6-db98-046b-267d92ad7ce3.png">


出てきた結果
[MacOS XからNode.jsをアンインストールする方法](http://d.sonicjam.co.jp/post/52541343939)

# 再確認
```
$ node -v
v4.5.0
```
えっ？？？消えてない。。。

```
$ which node
/usr/local/bin/node
```
発見 :bulb: ってことで再削除
```$ rm -rf /usr/local/bin/node```

# nodebrewインストール
ここからは結構簡単でした^^

```$ brew install nodebrew```

~/.bash_profile(zshなら~/.zshrc)に以下を追加
```export PATH=$HOME/.nodebrew/current/bin:$PATH```

ターミナル再起動 or 下記コマンド実行
```$ source ~/.bash_profile```

確認
```$ nodebrew help```

# Node.jsインストール
インストールできるNode.jsのversionを確認します。
```$ nodebrew ls-remote```

今回はv6.5.0をインストールします。
```$ nodebrew install-binary v6.5.0```

おやっ？？

```
Fetching: https://nodejs.org/dist/v6.5.0/node-v6.5.0-darwin-x64.tar.gz
Warning: Failed to create the file 
Warning: /Users/fukufuku/.nodebrew/src/v6.5.0/node-v6.5.0-darwin-x64.tar.gz: No 
Warning: such file or directory
curl: (23) Failed writing body (0 != 941)
download failed: https://nodejs.org/dist/v6.5.0/node-v6.5.0-darwin-x64.tar.gz
```
って感じで怒られたのでググります。。。
[nodebrew install がFailed to create the fileと怒られる] (https://blog.yug1224.com/archives/5693a5e0fef2539c7d5b149d)

とりあえず無いディレクトリを作成します。
```$ mkdir -p ~/.nodebrew/src```

もう一度インストールしてみます。

```
$ nodebrew install-binary v6.5.0
...
Installed successfully
```

成功したみたいなので確認

```
$ nodebrew ls
V6.5.0
```

使いたいバージョンを指定します。

```
$ nodebrew use v6.5.0
use v6.5.0
```

確認

```
$ node -v
v6.5.0
```

幸せ :heart_decoration:
PythonでMySQL 使ってみた[インストール・設定]

# MySQLインストール
まずは、インストールします。

```
$ brew install mysql
```

## MySQLの起動

```
$ mysql.server start
```
起動したら次に初期設定を行います。
## 初期設定

```
$ mysql_secure_installation
```

テストDBを残すかと聞かれたらNoでも大丈夫です。

## MySQLの実行

```
$ mysql -u root -p
```
先ほど設定したパスワードを入力すれば起動できます。

## 停止

```
$ mysql.server stop
```
jsで年度取得方法

年度を表示する必要があったので `moment` を利用してかんたんにできたのでメモしておきます。

# 年度の仕組み

[wiki](https://ja.wikipedia.org/wiki/%E5%B9%B4%E5%BA%A6)参照すると

> 会計など事務作業を目的としたものが中心で、またその多くは政府機関や業界団体等により決定されている。日本における具体的な年度の例としては、4月1日から翌年3月31日までを括る「会計年度」や「学校年度」などが一般にも用いられる。この区切りは明治時代から続く。

要するに3月末までは前年扱いになります。

# 実装

momentを利用して3ヶ月前の日付を取得して年を取得するだけです。

```js
const moment = require('moment');

moment('2016-12-31', 'YYYY-MM-DD').subtract(3, 'months').year();
// 2016
moment('2017-01-01', 'YYYY-MM-DD').subtract(3, 'months').year();
// 2016
moment('2017-03-31', 'YYYY-MM-DD').subtract(3, 'months').year();
// 2016
moment('2017-04-01', 'YYYY-MM-DD').subtract(3, 'months').year();
// 2017
```
Ansibleでパスワードをスマートに

## はじめに
ansibleでsshログイン時のパスワードを入力したり、sudo実行時のパスワード入力など
ansibleでパスワード入力をどう解決したらいいのか悩んでいる人向けの記事です。

## 解決方法
##### 1. playbookコマンド実行時のパラメータで指定（対話形式で入力）

`$ ansible-playbook sample.yml -i hosts --ask-pass --ask-sudo-pass`

##### 2. ansible.cfgで設定（上記パラメータ指定するのが面倒な方へ）

```ansible.cfg
ask_pass = True
ask_sudo_pass = True
```

##### 3. Ansible Vaultでパスワードを暗号化してパスワード入力を省略

```passwd.ymlを作成
---
ansible_sudo_pass: hoge
ansible_ssh_pass: hogehoge
```

```passwd.ymlを暗号化
$ ansible-vault encrypt passwd.yml
Vault password:
Confirm Vault password:
Encryption successful
```

```ansible.cfgにvaultのパスワードを要求するよう設定
ask_vault_pass = True
```


playbookコマンド実行時に外部変数として読み込む

```
$ ansible-playbook sample.yml -i hosts --extra-vars="@password.yml"
Vault password:
```

## 参考サイト
[Ansible で sudo を実行する](https://medium.com/makotows-blog/ansible-%E3%81%A7-sudo-%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B-bf7075c6feb0)
[（公式）ansible.cfg](https://docs.ansible.com/ansible/2.5/reference_appendices/config.html#ansible-configuration-settings)
RailsのSQLキャッシュと変数を使い回す場合のパフォーマンス比較、7000倍差

## 概要
SQLキャッシュを使うより、変数を使い回すほうが圧倒的に早い
例えば1ユーザの情報を表示するような場面ではパフォーマンスが気になるレベルではないと思われる。
表のようなデータを表示するような場合に同じデータをたくさん表示するような場合はちゃんと変数に入れたほうが、パフォーマンスが良い

## はじめに
RailsのActiveRecordの仕組みに同じSQLを何度も読んでもキャッシュしてくれて、都度DBにアクセスしなくて良い便利な仕組みがある。

この機能はかなり便利で雑にプログラミングしてもパフォーマンスが落ちにくい。落ちにくいがハイパフォーマンスを求められるところや、多量のデータを表示、作成するような場合だと影響を与えるような気がする。

そこでSQLキャッシュを使った場合と、普通に変数に保存した値を使いまわした場合でベンチマークをとってみた。

### SQLキャッシュが効いているかログで確認
キャッシュが効いていない場合のログはこのようにSQLを発行している

```
User Load (2.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 2], ["LIMIT", 1]]
```

キャッシュが効いる場合のログはこのように頭にCACHEがついている

```
CACHE User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
```

### 前提条件
Rails 5.1.4
Ruby2.5.0

### 測定
DBと連携しているUserモデルを呼び出し、ベンチマーク機能で10回、1000回測定している

#### SQLキャッシュを使う場合

```
@user = User.find(1)

User.benchmark("SQL cache") { 10.times { User.find(1) } }
SQL cache (7.9ms)
User.benchmark("SQL cache") { 1000.times { User.find(1) } }
SQL cache (705.2ms)
```

#### 変数に格納した値を使い回す場合

```
@user = User.find(1)

# 参照を渡すだけの場合
User.benchmark("plane val") { 10.times { user = @user } }
plan val (0.0ms)
User.benchmark("plane val") { 1000.times { user = @user } }
plan val (0.1ms)

# 値を複製して渡した場合（別のオブジェクトにする）
User.benchmark("plane clone val") { 10.times { user = @user.clone } }
plane clone val (0.1ms)
User.benchmark("plane clone val") { 1000.times { user = @user.clone } }
plane clone val (1.6ms)
```
### 結論
結果から圧倒的に変数を使いまわしたほうが速いことがわかる
雑に計測したら

* 参照で使い回す場合は7052倍早い
* 複製する場合で440倍速い

ということがわかった。

ジュニアレベルのプログラマへのアドバイスとして「メモリやCPU、ファイル読み込み、データベース、ネットワークの気持ちになってプログラミングしろ」とよく言うんだけど、大体半笑いされるんだけどさこの結果からもパフォーマンスが求められるレベルのことをやりたかったら前述のセリフは大事だよねというのがわかるはず。はずだよね？

### おまけ
キャッシュはおそらく設定ファイルのキャッシュの設定で動いているが、ファイルキャッシュとメモリキャッシュで設定を変えてみてもパフォーマンスの差は出なかった。ここらへん詳しい方コメント下さい

```
config.cache_store = :file_store
```

```
config.cache_store = :mem_cache_store
```


### 参考
ちなみにSQL Cacheを使わない場合と使った場合を測定したところ200倍速いそうだ
https://gist.github.com/ololobus/785f1005da29850d6a85

Railsは簡単にベンチマークがとれる
https://qiita.com/akishin/items/cf74559875cf475bbf66
acme.shでLet's Encryptのワイルドカード証明書を取得 with Nginx

Let's Encryptクライアントの[acme.sh](https://acme.sh/)を使ってワイルドカード証明書を取得してNginxでHTTPSするで。Apacheでもそんなに変わらんで。

設定やら何やらを入れても10分くらいで終わるで。

ほな行くでーー。

## スーパードゥ！

```zsh
sudo su -
```

## インストール

```zsh
curl https://get.acme.sh | sh
```

インストール直後はacme.shの設定を読み込む必要があるで。

```zsh
. ~/.acme.sh/acme.sh.env
```

## 設定

DNS認証で証明書を発行するための設定や。今回はCloudflareを使ってるけど、他にも色々対応しとるで。

詳しくは[Automatic DNS API integration](https://github.com/Neilpang/acme.sh#7-automatic-dns-api-integration)を参照や。

```diff:~/.acme.sh/account.conf
+ CF_Key='CloudflareのAPIキー'
+ CF_Email='Cloudflareアカウントのメールアドレス'
```

## 証明書発行

* `--issue` 証明書発行してや
* `--dns dns_cf` DNS認証でプロバイダはCloudflareや
* `-d` ドメインこれでよろしく

```zsh
acme.sh --issue --dns dns_cf -d example.com -d "*.example.com"
```

※120秒の待ち時間があるで。


## 証明書をインストール

今回はNginxで使うから近く（`/etc/nginx/ssl/*/`）に置くで。

```zsh
# ドメインごとのディレクトリを作るで
mkdir -p /etc/nginx/ssl/example.com
```

* `--install-cert` 発行済み証明書を（Web）サーバーにインストールしてや
* `-d` ドメインこれでよろしく
* `--key-file` key.pemの場所ここな
* `--fullchain-file` fullchain.pemの場所ここな
* `--reloadcmd` 終わったらこれ実行してな（**renew**時にも使われるで）

```zsh
acme.sh --install-cert -d example.com -d "*.example.com" \
--key-file /etc/nginx/ssl/example.com/key.pem \
--fullchain-file /etc/nginx/ssl/example.com/fullchain.pem \
--reloadcmd "service nginx force-reload"
```

## Nginxの設定

毎度お馴染みNginxのSSL設定やで。ググってや。

```nginx
ssl_certificate /etc/nginx/ssl/example.com/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/example.com/key.pem;
```

## 証明書の更新

* `--renew-all` 発行済み証明書を全部更新してや

```zsh
acme.sh --renew-all
```

## cronで証明書を自動更新

* `--cron` cron中に発行済み証明書を全部更新してや

```shell
# 毎週日曜日 23時13分に発行済み証明書を全部更新して欲しいんや
13 23 * * 0 /root/.acme.sh/acme.sh --cron > /root/.acme.sh/cron.log
```

`/etc/cron.weekly`とか`/etc/cron.monthly`に入れてもええで！！


あでゅ〜