OmniAICreator/Qiita-1.07M huggingface dataset:
MinGWでコンパイルしたMD5関数をVisual Studio(msvc)にリンクするまでのメモ

# キッカケ
[こちら](https://www.nayuki.io/page/fast-md5-hash-implementation-in-x86-assembly)に掲載されているMD5関数のテストプログラムを実行したところ、gcc on WSLでコンパイルすると頭一つ早い結果となった。(msvc/clangでは580 MB/s程度、gccでは約750 MB/s程度)
Windowsネイティブで同等の速度を出せないか試行錯誤をした。
「手段が目的」なので、単に自己満足だけである。
*おそらく、全部MinGW環境を構築してビルドすれば、この投稿に書く内容はやる必要はないと思われる。*

- cl.exe  
Microsoft(R) C/C++ Optimizing Compiler Version 19.15.26729 for x86
- clang-cl  
Microsoft(R) C/C++ Optimizing Compiler Version 19.15.26729 for x86
- clang on WSL  
clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)
- gcc on WSL  
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609

# msvcで試行錯誤してみたが
結論から言うとオプションを変えても、目立った効果はなかった。
`/Oy /Ot /Ob2 /Oi /O2`

# WSL(Ubuntu16.04)でクロスコンパイル
gccでビルドして、Intel記法でアセンブル出力する。

```sh
sudo apt install g++-mingw-w64-i686
i686-w64-mingw32-gcc-win32  md5.c -O3 -fomit-frame-pointer -S -masm=intel -fstack-protector
```

# Visual Studio に組み込む
クロスコンパイルで作成された*.SファイルをWindowsに持ってきて、Visual Studioのプロジェクトに組み込む。

## アセンブリファイルをビルド出来るようにする。
[こちら](https://kagasu.hatenablog.com/entry/2018/01/03/200337)を参考にした。

- [ビルドのカスタマイズ]をクリックする。
- [masm(.targets, .props)]を選択する。
- ビルドのカスタマイズで 追加した*.sファイルの項目の種類を`Microsoft Macro Assembler` に変更する。

これだけだとビルドしたときにエラー(`C++ LNK2026 モジュールは SAFESEH イメージには安全ではありません`)が発生して、リンクできない。
*.sファイルのプロパティで、[Microsoft Macro Assembler] - [Advanced]の Use Safe Exception Handlersを`はい(/safeseh)`に変更する。

## アセンブリファイルのディレクティブなどを編集する
そのままだとMASMで解釈できないディレクティブがあるので、
関数名のラベルとそれより前と、`ret`の後をMASM用に差し替える。
アセンブラは詳しく無いので、cl.exeの`/FAcs` の出力結果からほぼコピペしている。
今回対象にした関数は処理しかかなったが、データ割当などがあるとコピペはできないと思われる。

```diff
diff U5b md5.s md5_compress.s
--- md5.s	Mon Sep 17 12:29:36 2018
+++ md5_compress.s	Mon Sep 17 12:40:48 2018
@@ -1,15 +1,21 @@
-	.file	"md5.c"
-	.intel_syntax noprefix
-	.section	.text.unlikely,"x"
-LCOLDB0:
-	.text
-LHOTB0:
-	.p2align 4,,15
-	.globl	_md5_compress
-	.def	_md5_compress;	.scl	2;	.type	32;	.endef
-_md5_compress:
+	.686P
+	.XMM
+	include listing.inc
+	.model	flat
+
+INCLUDELIB MSVCRT
+INCLUDELIB OLDNAMES
+
+PUBLIC	_md5_compress
+EXTRN	@__security_check_cookie@4:PROC
+EXTRN	_memcpy:PROC
+EXTRN	_memset:PROC
+EXTRN	___security_cookie:DWORD
+_TEXT	SEGMENT
+
+_md5_compress PROC
 	push	ebp
 	push	edi
 	push	esi
 	push	ebx
 	sub	esp, 64
@@ -622,10 +628,8 @@
 	pop	ebx
 	pop	esi
 	pop	edi
 	pop	ebp
 	ret
-	.section	.text.unlikely,"x"
-LCOLDE0:
-	.text
-LHOTE0:
-	.ident	"GCC: (GNU) 5.3.1 20160211"
+_md5_compress ENDP
+_TEXT	ENDS
+END
```
Puppeteerを使って見る


# 基本

Webブラウザの操作をJavaScriptで自動化。Headless Chromeのフレームワーク「Puppeteer」がバージョン1.0に到達。ChromeのDevToolsチームが開発 － Publickey
https://www.publickey1.jp/blog/18/webjavascriptheadless_chromepuppeteer10chromedevtools.html

GoogleChrome/puppeteer: Headless Chrome Node API
https://github.com/GoogleChrome/puppeteer

Puppeteer v1.8.0
https://pptr.dev/

PuppeteerでヘッドレスChromeを操ってみる - Qiita
https://qiita.com/sand/items/b01d7d8f3d9c1642298b

PuppeteerでChromeを自動操作！｜開発室ブログ｜株式会社アクセスジャパン
https://access-jp.co.jp/blogs/development/39

puppeteerでよく使うであろう処理の書き方 - Qiita
https://qiita.com/rh_taro/items/32bb6851303cbc613124

Headless Chromeでファイルをダウンロードする - sambaiz-net
https://www.sambaiz.net/article/131/

Puppeteer wait page load after form submit - Stack Overflow
https://stackoverflow.com/questions/46948489/puppeteer-wait-page-load-after-form-submit?answertab=active#tab-top

javascript - JavaScriptスクレイピングとして puppeteer で画像やZipファイルなどをダウンロードしたい - スタック・オーバーフロー
https://ja.stackoverflow.com/questions/42047/javascript%e3%82%b9%e3%82%af%e3%83%ac%e3%82%a4%e3%83%94%e3%83%b3%e3%82%b0%e3%81%a8%e3%81%97%e3%81%a6-puppeteer-%e3%81%a7%e7%94%bb%e5%83%8f%e3%82%84zip%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%81%aa%e3%81%a9%e3%82%92%e3%83%80%e3%82%a6%e3%83%b3%e3%83%ad%e3%83%bc%e3%83%89%e3%81%97%e3%81%9f%e3%81%84?answertab=active#tab-top

# Nodeでreadline-sync

Node.jsでコマンドラインツール作るときに使いやすいreadline-sync | dotstudio
https://dotstud.io/blog/nodejs-npm-readline-sync/#%E9%81%B8%E6%8A%9E%E8%82%A2%E3%82%92%E5%87%BA%E3%81%97%E3%81%A6%E9%81%B8%E3%81%B0%E3%81%9B%E3%82%8B

# Nodeでimportをつかう

sdkの補完を効かせるため

Node v9 で ES Module import を使ってみる - Qiita
https://qiita.com/ryohji/items/93f5050b9af6fc15693c

# 試したもの

https://gist.github.com/bonk/1f7a6da088a2796fe3e6ce76f50bf9e7
Azure CLIでサブスクリプションリストをリフレッシュする

[ドキュメント](https://docs.microsoft.com/ja-jp/cli/azure/account?view=azure-cli-latest#az-account-list)にオプションが書かれていて、 --refreshをつければよいとのこと。

```sh
az account list --refresh
```

以下の状況だったので試しました。

* サブスクリプションを追加したとき、デフォルトで「従量課金」という名前が付いていたので、名前を変更
![2018-09-17_11h38_23.png](https://qiita-image-store.s3.amazonaws.com/0/47737/3fd15513-c5a7-b361-1a64-31d83400ffa3.png)


* Azure CLIでサブスクリプションのリストを取得

```sh
az account list --all
```

* 古いサブスクリプション名(下の「\u5f93\u91cf\u8ab2\u91d1」はデコードすると「従量課金」）が取得される

```json
[
  {
    "cloudName": "AzureCloud",
    "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "isDefault": false,
    "name": "Visual Studio Professional with MSDN",
    "state": "Disabled",
    "tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "user": {
      "name": "hoge@example.com",
      "type": "user"
    }
  },
  {
    "cloudName": "AzureCloud",
    "id": "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy",
    "isDefault": true,
    "name": "\u5f93\u91cf\u8ab2\u91d1",
    "state": "Enabled",
    "tenantId": "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy",
    "user": {
      "name": "hoge@example.com",
      "type": "user"
    }
  }
]
```

* 冒頭のリフレッシュコマンドを実行

```sh
az account list --refresh
```

実行すると更新されたサブスクリプション名が表示されました。
![2018-09-17_11h39_54.png](https://qiita-image-store.s3.amazonaws.com/0/47737/0123fecf-31a4-bb0b-a3c7-a43426d9e3bc.png)

* 再度取得

```sh
az account list --all
```
今度はちゃんと更新されたサブスクリプション名で取得できました。

```json
[
  {
    "cloudName": "AzureCloud",
    "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "isDefault": false,
    "name": "Visual Studio Professional with MSDN",
    "state": "Disabled",
    "tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "user": {
      "name": "hoge@example.com",
      "type": "user"
    }
  },
  {
    "cloudName": "AzureCloud",
    "id": "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy",
    "isDefault": true,
    "name": "kikutarosubscription",
    "state": "Enabled",
    "tenantId": "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy",
    "user": {
      "name": "hoge@example.com",
      "type": "user"
    }
  }
]
```
GenymotionにGooglePalyを入れたらネットワークに接続できなくなった

# 経緯
Android Studioの実行環境として、AndroidエミュレータのGenymotionを利用していたが、GooglePlayを入れようとした際ネットワークに接続できなくなったので、その解決方法をメモ。

# GooglePlayを入れる
以下のサイトを参考にして、[Open GApps](https://opengapps.org/)からzipファイルをダウンロードする。

参考サイト: [AndroidシミュレータGenymotionに Google Play ストア をインストール（2017）](https://qiita.com/sou_lab/items/bb06bb653b291c90bf45)

###しかし...
GenymotionにGooglePlayは入ったのだが、ネットワークに接続できなくなっている。
原因がよくわからず、先程のサイトをよく見返してみたら、冒頭に古い情報のやり方について触れてあり、その方法でやってみたらネットワークに接続できた。

# Genymotion-ARM-Translationをダウンロードする
以下のサイトを参考にして、[Genymotion-ARM-Translation v1.1.zip](https://www.androidfilehost.com/?fid=23252070760974384)をダウンロードする。
参考サイト: [Androidエミュレーター「Genymotion」でGoogle Playアプリが利用できる環境の作り方](https://nelog.jp/how-to-use-google-play-in-genymotion)

ダウンロードしたzipファイルをGenymotionの画面にドラッグ&ドロップして再起動します。



接続できました！
![2018-09-17 (1).png](https://qiita-image-store.s3.amazonaws.com/0/278251/27cf7430-3e3f-a63e-95c2-94e84156d17c.png)
Rails5でjQueryプラグインのロードで couldn't find fileエラー

jQueryプラグインを入れようとしたらファイル無いと怒られてしまった。

```
ActionView::Template::Error (couldn't find file 'jquery.waypoints.min' with type 'application/javascript'
```

## ディレクトリ構成
```
vendor
 └ assets
    └ javascripts
       └ jquery.waypoints.min.js
```

- `app/assets`: アプリケーション自身が保有するアセット置き場
- `lib/assets`: 共有ライブラリのアセット置き場
- `vendor/assets`: サードパーティー製のアセット置き場

**参考** ：[アセットパイプライン アセットの編成 | Rails ガイド ](https://railsguides.jp/asset_pipeline.html#%E3%82%A2%E3%82%BB%E3%83%83%E3%83%88%E3%81%AE%E7%B7%A8%E6%88%90) 


## 読み込みの設定
圧縮ファイルだったため、`.min`まで記載

```app/assets/javascripts/application.js
//= require_tree .
//= require jquery.waypoints.min
//= require_directory .
```

**補足**
パスは単純に`assets/*`で検索しているとのことなので、
`//= require_tree ../../../vendor/assets/javascripts/.` は記載していない。
**参考** : [アセットパイプライン パスの検索 | Rails ガイド ](https://railsguides.jp/asset_pipeline.html#%E3%83%91%E3%82%B9%E3%81%AE%E6%A4%9C%E7%B4%A2)

### 解決方法
アセットのパス配列は、サーバーの起動時に一度設定されており、 `/vendor/assets/javascripts`にサブフォルダが存在しない場合、Railsはそこを参照しないとのこと。

>[Rails 5 doesn't load js file in vendor/assets/javascripts directory](https://stackoverflow.com/questions/45221349/rails-5-doesnt-load-js-file-in-vendor-assets-javascripts-directory)
> It seems that the asset paths array is populated once when the server starts. If any of the subfolders of /vendor/assets/javascripts did not exist then Rails will not be looking there

`/vendor/assets/`配下が読み込まれるよう、サーバーのリロードを行ったところ解決
AWS CLI をインストールする

# 目的

aws コマンドをローカルで叩けるようにする。

# 環境

- macOS High Sierra 10.13.6
- pyenv 1.2.7
- Python 3.6.3
- pip 18.0

# AWS CLI のインストール

[macOS で AWS Command Line Interface をインストールする \- AWS Command Line Interface](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-install-macos.html) を参考にする。

- [バンドルされたインストーラを使用して AWS CLI をインストールする](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-install-macos.html#install-bundle-macos)
- [バンドルされたインストーラを使用して AWS CLI をインストールする](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-install-macos.html#awscli-install-osx-pip)

という2つの方法があるようだが、pip で入れたほうがアップグレードが簡単そうなので pip で入れる。

```bash
$ pip --version
pip 18.0 from /Users/yuichiro/.pyenv/versions/3.6.3/lib/python3.6/site-packages/pip (python 3.6)
$ pip3 install awscli --upgrade --user
$ aws --version
-bash: aws: command not found
```

`command not found` と言われた。

[AWS CLI 実行ファイルをコマンドラインパスに追加する](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-install-macos.html#awscli-install-osx-path) によると

> pip のインストール後は、OS の aws 環境変数への PATH 実行ファイルの追加が必要になる場合があります。

ということなので、やっていく。

```bash:~/.bash_profile
# pip で --user をつけると .local 以下にインストールされる
export PATH=~/.local/bin:$PATH
```

```bash
$ source ~/.bash_profile
$ aws --version
aws-cli/1.16.14 Python/3.6.3 Darwin/17.7.0 botocore/1.12.4
```

OK!!

`pip install` に `--user` をつけると `~/.local/` 以下にインストールされるので、 `~/.local/bin` に PATH を通す必要があるということだろう。

```bash
$ tree -L 2 ~/.local
/Users/yuichiro/.local
├── bin
│   ├── aws
│   ├── aws.cmd
│   ├── aws_bash_completer
│   ├── aws_completer
│   ├── aws_zsh_completer.sh
│   ├── pyrsa-decrypt
│   ├── pyrsa-decrypt-bigfile
│   ├── pyrsa-encrypt
│   ├── pyrsa-encrypt-bigfile
│   ├── pyrsa-keygen
│   ├── pyrsa-priv2pub
│   ├── pyrsa-sign
│   └── pyrsa-verify
├── lib
│   └── python3.6
└── share
    ├── heroku
    └── recently-used.xbel
```

# AWS CLI の設定

[AWS CLI の設定 \- AWS Command Line Interface](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-getting-started.html) を参考にする。
App Maker + Google Cloud SQL の組み合わせで使ってみる(フォームでデータ追加)

[App Maker + Google Cloud SQL の組み合わせで使ってみる(テーブルで画面表示)](https://qiita.com/kamina/items/8f6da0dc119e20381704)の続きになります。

前回まででDBのデータを画面に表示・編集できるようになりましたので、今回はデータを追加してみます。

# フォームウィジェットの追加
まずは、WidgetsからFormを追加します。
（前回作成したテーブルは右側に移動しています。）
![フォームの追加.png](https://qiita-image-store.s3.amazonaws.com/0/272546/f1865620-bbec-7cf3-75d3-d3a5c2fb36ad.png)

すると、テーブル追加同様にデータソースを選べと出るので、TestModelを選択してNEXT。
![データソース選択.png](https://qiita-image-store.s3.amazonaws.com/0/272546/596d7d03-1c48-c7e5-8684-05453fb17a6b.png)

次はフォームのタイプを選べと出るので、今回はInsertを選択します。
![フォームタイプ選択.png](https://qiita-image-store.s3.amazonaws.com/0/272546/b2343c91-c200-2864-6bfb-a07d0f37b7d1.png)

カラムの選択となるので、今回は自動採番(Auto Increment)のIdのチェックは外します。
ちなみに、タイプをInsertにしているので、各項目のEditableは選択できません。
![カラムの選択２.png](https://qiita-image-store.s3.amazonaws.com/0/272546/5ec608cc-dafa-6e6d-eb66-8df1ba8256d7.png)

そうすると、下記のようにフォームが追加されます。
今回もいろいろと自動でパーツが配置されているかと思います。
（右側にあるのは前回作成した表示用のテーブルです。）
![フォーム.png](https://qiita-image-store.s3.amazonaws.com/0/272546/0e4b78a5-e559-ff22-803f-f5125730d2c3.png)

# 動かしてみる
では、早速動か(PREVIEW)してみましょう。
![フォームプレビュー.png](https://qiita-image-store.s3.amazonaws.com/0/272546/9da62b06-4e63-5e2e-77bb-2b04cceb92f0.png)

適当に入力してSUBMITすると、無事にデータが追加されます。
しかも、隣の表示用のテーブルも自動でリロードされるという。至れり尽くせりですね。

# おわりに
はい、というわけでApp MakerとGoogle Cloud SQLの接続から、モデルの作成、データの表示・編集・追加と、最低限のことは一通りできるようになったかと思います。
コーディングなしにここまでできるとか、便利になったものです。
チューニングを必要とするような大規模なシステムには向かないかもしれませんが、小規模な社内業務系アプリ開発には大いに活用できると思います。
App MakerはG SuiteのBusinessプラン以上であれば使うことができますので、活用してみては如何でしょうか。
ClojureScriptでReactチュートリアルやってみた (2)

# はじめに
[この記事](https://qiita.com/onishi024/items/e97e1f10bebba5b95b7a)の続き。

[公式チュートリアルの「Wrapping Up」の章(最後)](https://reactjs.org/tutorial/tutorial.html#lifting-state-up-again)まで進めてみました。部品の大部分をBoardコンポーネントからGameコンポーネントに移し、`history`に盤面を保存していくように変更しています。

全ソースは[こちら](
https://github.com/onishi024/react-tutorial-cljs/blob/789e3e44476d415b190dbf5448c4c066d2af97f1/src/react_tutorial/core.cljs)。

# 1. 実装

```cljs
(defn square [{:keys [on-click value]}]
  [:button.square
    {:on-click #(on-click)}
    value])

(defn board [& {:keys [squares on-click]}]
  (letfn
    [(render-square [i]
       [square {
         :value (squares i)
         :on-click #(on-click i)
       }])]
        [:div
          [:div.board-row
            (render-square 0)
            (render-square 1)
            (render-square 2)]
          [:div.board-row
            (render-square 3)
            (render-square 4)
            (render-square 5)]
          [:div.board-row
            (render-square 6)
            (render-square 7)
            (render-square 8)]]))

(defn game []
  (let [state (r/atom {:history (vec [{:squares (vec (repeat 9 ""))}])
                       :x-is-next? true})]
    (fn []
      (letfn
        [(handle-click [i]
          (let [history (get @state :history)
                current (last history)
                squares (get current :squares)
                x-is-next? (get @state :x-is-next?)]
            (when (and (= (calculate-winner squares) nil) (= (squares i) ""))
                  (swap! state
                         assoc :history
                         (conj history
                               (assoc-in current [:squares i] (if x-is-next? "X" "O"))))
                  (swap! state assoc :x-is-next? (not x-is-next?)))))]
            (let [history (get @state :history)
                  current (last history)
                  squares (get current :squares)
                  winner (calculate-winner squares)
                  status (if (= winner nil)
                              (str "Next player: " (if (get @state :x-is-next?) "X" "O"))
                              (str "Winner: " winner))]
                    [:div.game
                      [:div.game-board
                        [board :squares squares
                               :on-click handle-click]
                        ]
                    [:div.game-info
                      [:div status]
                    [:ol
                    ;"todo"
                    ]]])))))
```

# 2.ClojureScriptコーディングあれこれ

## 2.1. last

```cljs
(last history)
```
`last`はcollectionの最後の要素を取得する。

## 2.2. conj

```cljs
(conj history
      (assoc-in current [:squares i] (if x-is-next? "X" "O")))
```

`conj`はcollectionの最後に要素を追加する。

# 続き
[こちら](https://qiita.com/onishi024/items/6bfe9d4051f1bc155bd6)
CLIでcomposer.jsonのautoloadを追加する方法

`composer.json`には`autoload`セクションがあるが、それをエディタではなくコマンドで追加するには、`jq`コマンドを用いいて次のようにするとできる。

```shell
cat composer.json | jq --indent 4 '.autoload."psr-4"."Vendor\\Package\\" =  "src"' | tee composer.json
```
Scikit-learnを使って教師あり学習(線形単回帰)をしてみた[基礎]

#内容
Scikit-learnの`LinearRegression`を使って、bostonデータセットの単回帰分析をやってみようと思います。今回はモデルを構築して単純に回帰分析をします。

単回帰分析とは、モデルの学習に`boston.data[:, [5]]`(部屋数)１つだけ(説明変数１つ)で学習することをいいます。

#データセットの読み込み

```python
from sklearn.datasets import load_boston
from sklearn.linear_model import LinearRegression
import pandas as pd

# bostonデータセットの読み込み
boston = load_boston()
```

>補足bostonデータセットのDataFrameの作成
ただ単にデータセットを読み込んだだけだど以下のようになってしまうので、DataFrameにします。
<img width="1068" alt="スクリーンショット 2018-09-17 0.22.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/285122/e215e39a-e4df-655e-1aaf-aa6ac4a21bb8.png">


>```python
boston_df = pd.DataFrame(data=boston.data,columns=boston.feature_names)
boston_df['PRICE'] = boston.target
```
><img width="779" alt="スクリーンショット 2018-09-17 0.45.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/285122/50784ac7-1e87-6139-12c3-5a42ce49b3ba.png">


>これで見やすい形になりました。
それぞれのカラムの内容なこんな感じです。

>・CRIM・・・犯罪発生率（人口単位）
・ZN・・・25,000平方フィート以上の住宅区画の割合
・INDUS・・・非小売業の土地面積の割合（人口単位）
・CHAS・・・チャールズ川沿いかどうか（1:Yes、0:No）
・NOX・・・窒素酸化物の濃度（pphm単位）
・RM・・・1戸あたりの平均部屋数
・AGE・・・1940年よりも前に建てられた家屋の割合
・DIS・・・ボストンの主な5つの雇用圏までの重み付きの郷里
・RAD・・・幹線道路へのアクセス指数
・TAX・・・10,000ドルあたりの所得税率
・PTRATIO・・・教師あたりの生徒の数（人口単位）
・B・・・アフリカ系アメリカ人居住者の割合（人口単位）
・LSTAT・・・低所得者の割合
・PRICE・・・住宅価格


#予測

```python
# モデルの構築
model = LinearRegression()

#　モデルの学習
# boston.data[:, [5]]はRM(部屋の数)、boston.target(住宅の価格)
model.fit(boston.data[:, [5]],boston.target)

# 予測精度
score = model.score(boston.data[:, [5]],boston.target)

print(score)
```

このような感じでScikit-learnを使えば簡単に単回帰分析が行えます。
php-master-changes 2018-09-16

# 2018-09-16
## cmb69: Revert "Implement [#67331](https://bugs.php.net/bug.php?id=67331): Have parse_ini_file add empty entries"
- https://github.com/php/php-src/commit/6da3a1e3ce8726054f87f6cc63210bf4760c680d
- [昨日の parse_ini_file() の機能追加](https://qiita.com/sj-i/items/8fae2cd16916e954d9c9#cmb69-implement-67331-have-parse_ini_file-add-empty-entries)を revert
- Windows でテストが壊れたので

## Fleshgrinder: Silence ar warning
- https://github.com/php/php-src/commit/a25171b96dd20891b09ba3b9dd7df95986cff293
- automake のバグによる警告を抑制
- [PR](https://github.com/php/php-src/pull/3017) 上にもう少し細かい話

## cmb69: Update to SQLite 3.25.0
- https://github.com/php/php-src/commit/ba300b69d2944678e5d8164b7abd99bf296ff06e
- ext/sqlite3 を SQLite 3.25.0 に更新

## nikic: Make ext/xml API private
- https://github.com/php/php-src/commit/ca6caa0cb28b4e6d426f925e929baf06e29ae8dd
- ext/xml の内部 API を private に
- あわせて不要コードを削除

## nikic: Remove IS_EXT_MODULE defines
- https://github.com/php/php-src/commit/1d0252a1c085b076fa63511439685ef2bd070987
- 幾つかの拡張で定義されていた IS_EXT_MODULE マクロを削除
- 何に使われていたものかは不明

## nikic: Remove checks for libxml < 2.6.11
- https://github.com/php/php-src/commit/2d81db5643feb9e03a4417b4b5ce53b32d7dab47
- 最低要求バージョンの 2.6.11 より低いバージョンの libxml 用のチェックを削除
Pythonの仮想環境とパッケージ on Windows

# はじめに

- 詳しく知りたい人は、[公式のチュートリアル](https://docs.python.org/ja/3/tutorial/venv.html)へどうぞ。
 - [Ubuntu版はこちら](https://qiita.com/sireline/items/3c97a0c266431ac5b2ea)
- Python3自体のインストールは済んでいる前提です。
- Python2は扱いません。

# venvで仮想環境の構築

```py:仮想環境の構築
C:\pystudy>python -m venv myenv
```

```py:有効化
C:\pystudy>myenv\Scripts\activate.bat
```

```py:pipのバージョンが古いと怒られる
(myenv) C:\pystudy>pip list
pip (7.1.2)
setuptools (18.2)
You are using pip version 7.1.2, however version 18.0 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.
```

```py:pipをアップグレードする
(myenv) C:\pystudy>python -m pip install --upgrade pip
Collecting pip
  Using cached https://files.pythonhosted.org/packages/5f/25/2dda...940/pip-18.0-py2.py3-none-any.whl
Installing collected packages: pip
  Found existing installation: pip 7.1.2
    Uninstalling pip-7.1.2:
      Successfully uninstalled pip-7.1.2
Successfully installed pip-18.0
```

```py:インストールされているパッケージを表示する
(myenv) C:\pystudy>pip list
Package    Version
---------- -------
pip        18.0
setuptools 18.2
```

```py:パッケージを探す
(myenv) C:\Apache24\htdocs\kaggle>pip search numpy
numpy (1.15.1)                        - NumPy: array processing for numbers, strings,
                                        records, and objects.
numpy-sugar (1.2.8)                   - Missing NumPy functionalities
numpy-turtle (0.1)                    - Turtle graphics with NumPy
msgpack-numpy (0.4.3.1)               - Numpy data serialization using msgpack
:
pyscience11 (0.5)                     - C++11 wrapper for NumPy, SciPy and Matplotlib

# ワイルドカードで検索とか出来たらいいのになぁ...
# pip search mat*
```

```py:パッケージをインストールする
(myenv) C:\pystudy>pip install numpy
Collecting numpy
  Using cached https://files.pythonhosted.org/packages/b7/a7/b99...b47/numpy-1.15.1-cp35-none-win_amd64.whl
Installing collected packages: numpy
Successfully installed numpy-1.15.1
```

```py:パッケージをアンインストールする
(myenv) C:\pystudy>pip uninstall numpy
Uninstalling numpy-1.15.1:
  Would remove:
    c:\pystudy\myenv\lib\site-packages\numpy-1.15.1.dist-info\*
    c:\pystudy\myenv\lib\site-packages\numpy\*
    c:\pystudy\myenv\scripts\f2py.py
Proceed (y/n)? y
  Successfully uninstalled numpy-1.15.1
```

```py:パッケージの環境を配布する
# 仮想環境1を構築する
# 有効化する
# パッケージを色々入れて構築する
# 構築したパッケージのリストをファイルに書き出す
(myenv) C:\pystudy>pip freeze > requirements.txt
# 無効化する
:
# gitでrequirements.txtを配布する
:
# 誰かさんは仮想環境を構築する
# 有効化する
# pipをアップグレードする
# ファイルからパッケージを構築する
(yourenv) C:\your_dir>pip install -r requirements.txt
```

```py:無効化
C:\pystudy>myenv\Scripts\deactivate.bat
```

```py:仮想環境を初期化する
C:\pystudy>python -m venv --clear myenv
```

```py:仮想環境を削除する
C:\pystudy>rmdir /s myenv
myenv、よろしいですか (Y/N)? y
```

# おわりに
- 最後までお付き合いいただきありがとうございました。
- Python楽しいですね。
Ubuntu 18.04 画面解像度・マルチモニターのエラー対処

Ubuntu 18.04にアップデートしたら、画面設定がおかしすぎてめちゃめちゃ時間を取られた。

まず、画面の解像度が選べない。そして私はマルチモニター（デュアルディスプレイ）なのだが、１つの画面しか認識していない。

くそったれと思いながら、ドライバの更新だったり、画面解像度の設定をCUIから打ったりしたけど、結局は１つのコマンドで全て解決できたので、共有しておく。



#前準備
まずはお約束の

```
sudo apt update
sudo apt upgrade
```

#画面解像度、マルチモニター設定の解決コマンド
以下のコマンドだけで全て解決しました。cuda-toolkitを使ってインストールすることが重要みたいですね。
このコマンドを見つけるまでにいろんなnvidiaドライバもインストールしてしまったのですが、
以下のコマンドが全て自動で消してくれました。

ちなみに私のGPUはNVIDIA Geforce 1080Tiなので、nvidia-driver-390の「390」の部分は
GPUによって変えないといけないかもです。

```
sudo apt install nvidia-cuda-toolkit nvidia-driver-390
sudo reboot
```

元は[こちら](https://qiita.com/yukoba/items/4733e8602fa4acabcc35)の方の記事を参考にしましたが、この記事にたどり着くまでに２時間くらいかかってしまいました。

備忘録なのでこのへんで。
Ubuntu 18.04にアップグレードしたけど、解像度の設定が選べない！　３：４になってる！　マルチモニター・デュアルモニターを認識しない！

と困ったら、上記のコマンドを試してみて下さい。
GoenvとVSCodeでGoのデバッグ環境を作った

Goenvの環境構築やら、Go自体の環境セットアップ等々あるけど、
いろいろつまづきながら進んだので、今後つまづかないためのメモ。

本当は、[Goならわかるシステムプログラミング](http://ascii.jp/elem/000/001/235/1235262/)を読みたかっただけなんです。
~~本を買うお金がないのとIntelliJでGoが使えなくなったので代替案で作った~~


## 自分の環境

+ MacBook Pro
+ Zsh(書いてある内容はzsh部分をbashに置き換えてもいけるはず)
+ Brew
+ GO 1.10.0(Goenvでいつでもバージョン変えられるようにしておく)


## Goenvのインストール

まずはGoをMacにインストールする
とはいえ、いつでもバージョンを変えられるようにしたいのでせっかくだからGoenvをインストールする
インストールはBrewで。

```sh
brew install goenv
```

その後zshrcにPATHを追記しておく。

```
#GOENVのPATH設定
export PATH="$HOME/.goenv/bin:$PATH"
eval "$(goenv init -)"

#GOPATHの設定(PATHの場所は自由に)
export GOPATH=$HOME/.go
PATH=$PATH:$GOPATH/bin
```

```
source ~/.zshrc
```

最後にGoenvからGoをインストールし、有効にしておく。

```
goenv install 1.10.0
goenv global 1.10.0
```

## delveインストール
Goのデバッガ用にdelveをインストール

```
go get github.com/derekparker/delve/cmd/dlv
```

## VSCode側の設定

VSCodeを起動

Extensionに移動し、Goをインストール

<img width="761" alt="go1.png" src="https://qiita-image-store.s3.amazonaws.com/0/121758/f29c5b7a-af7a-b36d-649e-86366c5b9c21.png">

デバッグからAdd configration -> Go launch fileを開く
jsonファイルはデフォルトのままでOK

これで動くはず。。。

### import "fmt"で行き詰まった!

``import "fmt"``とうってもimportできなかったので複数インポートする場合の

```
import (
 "fmt"
)
```

と書くと動いた。
バージョンの問題なのかも。。。

### ~~オレオレ~~証明書の作成ならびに紐付け
もしかするといらないかもですが、IntelliJで書いていた証明書の設定を書いておきます。

まずFinderまたはApplicationから``Keychain Access.app(キーチェーンアクセス)``を開きます。
キーチェーンアクセスタブより、証明書アシスタント -> 証明書の作成をクリック

<img width="534" alt="go3.png" src="https://qiita-image-store.s3.amazonaws.com/0/121758/5b9c9806-6061-9c3b-22c0-ab5bbd413bab.png">

証明書名を適当に入力、それ以外は以下の画像の通り。

<img width="728" alt="go4.png" src="https://qiita-image-store.s3.amazonaws.com/0/121758/41077568-53f9-4474-b6dc-c1ebeb3e4581.png">

あといくつか設定があるがそのまま続けるを押す(有効期間は必要に応じて)
最後に証明書の場所の指定があるので**システム**を選択し、作成ボタンを押す。

最後に、作成した証明書をGoに紐付けます。

```
cd $GOPATH/src/github.com/derekparker/delve
CERT=gosyspro make install
```


### 最後に
これから上の記事を読み進めていくので、行き詰まったら本記事修正します。

###　参考文献

http://ascii.jp/elem/000/001/234/1234843/
https://qiita.com/TsuyoshiUshio@github/items/e942002be908f36bf6d4
http://lgtm.hatenablog.com/entry/2015/09/11/115001
Sentryでバグレポートを受け取る【React Native Expo】

https://docs.expo.io/versions/latest/guides/using-sentry.html

## Sentryとは
アプリケーションからイベントログを送信してくれるもの。
https://sentry.io/

Expoに対応している([bugsnagはExpo未対応](https://github.com/bugsnag/bugsnag-react-native/issues/137))

## 導入方法

### 登録してプロジェクト作成
- [Sentryに登録する](https://sentry.io/signup/)

- 言語やフレームワークを選択、project nameを記入してCreate Projectする

- 下の方にあるPublic DSNをコピーしておく(`Sentry.config('https://**********@sentry.io/***').install();`みたいな所のアドレス部分)

- [Sentry API](https://sentry.io/settings/account/api/auth-tokens/)でauth tokenを作成(設定はデフォルトでOK)、auth tokenをコピーしておく

- ダッシュボードに行き、プロジェクトのsettingsタブからNameをコピーしておく

- 左上のボタンからOrganization settingsに行き、Nameをコピーしておく 

### Sentryをインストール、設定する

- `async/await`を利用するため、Node 7.6+であることを確認
- `npm i sentry-expo --save`
- `App.js`に以下を追加


```App.js
import Sentry from 'sentry-expo';

// Remove this once Sentry is correctly setup.
Sentry.enableInExpoDevelopment = true;

Sentry.config('your Public DSN goes here').install();
```

- `app.json`に`postPublish hook`を追加、先ほどコピーした項目を記入してください

```app.json
{
  "expo": {
    // ... your existing configuration

    "hooks": {
      "postPublish": [
        {
          "file": "sentry-expo/upload-sourcemaps",
          "config": {
            "organization": "your organization's short name here",
            "project": "your project name here",
            "authToken": "your auth token here"
          }
        }
      ]
    }
  }
```


## 動作確認
強制的にエラーを発生させてみます(Button追加)
https://docs.sentry.io/clients/javascript/usage/

```App.js
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import Sentry from 'sentry-expo';

// Remove this once Sentry is correctly setup.
Sentry.enableInExpoDevelopment = true;

Sentry.config('https://********@sentry.io/****').install();

export default class App extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text>Open up App.js to start working on your app!</Text>
        <Text>Changes you make will automatically reload.</Text>
        <Text>Shake your phone to open the developer menu.</Text>
        <Button onPress={() => {throw new Error('sample error from expo')}} title="broken"/>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});
```

Sentryのダッシュボードでエラーを確認できました
![5416238b-cbe2-45ed-8fcf-9917460ca8fe.png](https://qiita-image-store.s3.amazonaws.com/0/196629/fc68438e-f397-d2dd-5e58-bc829176c275.png)
Expo環境のDetoxではテスト成果物(Artifacts)を利用できない話

## Detoxとは
https://github.com/wix/detox/
モバイルアプリでE2Eテストの自動化を行えるライブラリ

## テスト成果物(Artifacts)とは
Detoxでは、v8からE2Eテストの結果を成果物(Artifacts)として記録しておくことができます。
https://github.com/wix/detox/blob/master/docs/APIRef.Artifacts.md
具体的には以下のような記録を残すことが可能です。
- `.log`形式のログ
- `.png`形式のテスト前後のスクリーンショット
- `.mp4`形式のテスト中の画面遷移の動画

## 何が問題か
React Native ExpoでDetoxを利用するときは`detox-expo-heplers`を利用しなければなりません
https://github.com/expo/detox-expo-helpers

通常であれば、Expoを起動した後に`reloadApp`を呼び出して自分のアプリを読み込むのですが、Detoxの問題でv7.2.0以降は読み込み完了が取れずテストがここで止まってしまいます。

```firstTest.spec.js
const { reloadApp } = require('detox-expo-helpers');

describe('Example', () => {
  beforeEach(async () => {
    await reloadApp();
    // これ以降には進まない
  });

  it('should have welcome screen', async () => {
    await expect(element(by.id('welcome'))).toBeVisible();
  });
});
```

https://github.com/expo/detox-expo-helpers/issues/8


## 結局
Expoでdetoxを使いたい場合、テスト成果物は諦めてv7.2.0を利用しましょう(React Nativeは大丈夫)
Goで定期的にTweetするTwitter Botを作ってみる

## 概要
土曜の昼下がり、特に何をするでもなく、やる気が出なかったので、手元の日めくりカレンダーを毎日1回つぶやいてくれるTwitterBotでも作ろうかなと考えて、Goで作ってみました。ただ、そこらへんのbotサービスに登録するのではつまらないので、自分でロジックも考えてみようという意図です。あと、個人的に1時間に一回とか呟くbotは自分のタイムラインがうまってしまってノイズになるので、毎日1回ツイートするくらいのゆるゆるbotにしました。TwitterのAPIを処理してくれるGoのパッケージ`anaconda`を使うとともに、`ticker`で時間の概念を導入してみました。

## Twitter APIの取得
TwitterでTweetしたり、タイムラインを取得したりするためには、APIキーとアクセストークンが必要になります。Twitterアカウントを作ったら、APIを使うために次のリンクから登録しましょう。
https://apps.twitter.com/

実装で使うのは、`API Key`,`API Secret`,`Access Token`,`Access Token Secret`の4つになります。

## Goファイルの作成
フォルダの構造は以下のようになり、`keys.go`,`text.go`,`main.go`を3つのファイルを作ります。

```
tweetbot/
├── keys
│   └── keys.go
├── text
│   └── text.go
├── main.go
```
```go:keys.go
package keys

import (
"github.com/ChimeraCoder/anaconda"
)

func GetTwitterApi() *anaconda.TwitterApi {
	anaconda.SetConsumerKey("")
	anaconda.SetConsumerSecret("")
	api := anaconda.NewTwitterApi("", "")
	return api
}
```
先ほどの`API Key`,`API Secret`,`Access Token`,`Access Token Secret`を順番に入れていくだけです。

```go:text.go
package text

import (
	"time"
	"fmt"
)

func ChooseTweet()string{

	TweetList :=  [31]string{
		"投稿の内容を書く" ,
		//省略
	}

	d := time.Now().Day()
	m := time.Now().Month()

	TweetContent := TweetList[d-1]
	TweetOfToday := fmt.Sprintf("【%d月%d日】\n %s",m,d, TweetContent)
	return TweetOfToday
}
```
配列`TweetList`から今日呟く内容を抽出する関数`ChooseTweet()`を作ります。
Twitterでは、同じ内容を呟くと、`Status is a duplicate`というエラーが出るので、最初に【何月何日】を追加することにしました。

```go:main.go
package main

import (
"fmt"
"time"
. "fmt"
. "./keys"
. "github.com/***/tweetbot/text" //text.goをgithubにあげて、go getをした
)

func main() {
	chStop := make(chan int, 1)
	TimerFunc(chStop)

	time.Sleep(time.Hour * 24 * 365)
	chStop <- 0 // Tickerをstopさせるメッセージ

	close(chStop)

	time.Sleep(time.Second * 1)

	fmt.Println("Application End.")
}

func TimerFunc(stopTimer chan int) {
	go func() {
		ticker := time.NewTicker(24 * time.Hour) // 1日間隔のTicker

	LOOP:
		for {
			select {
			case <-ticker.C:
				api := GetTwitterApi()
				text := ChooseTweet()

				tweet, err := api.PostTweet(text, nil)
				if err != nil {
					panic(err)
				}
				Print(tweet.Text)
				//}
			case <-stopTimer:
				fmt.Println("Timer stop.")
				ticker.Stop()
				break LOOP
			}
		}
		fmt.Println("timerfunc end.")
	}()
}
```
## バックグラウンドで実行
```bash
$ go build main.go -o tweetbot
$ ./tweetbot & #バックグラウンドで実行
```
下記のコマンドでtwwetbotが動いているプロセスを確認できます。

```bash
$ ps aux |grep tweetbot
```
止めたいときは、`kill`します。

```bash
$ kill プロセス番号
```

## まとめ
毎日一回しかTweetしないなら、手動でいい説が濃厚...
今回作ったbotもぜひフォローしてください！
Twitter [@inspireverybody](https://twitter.com/inspireverybody)

## 参考
https://qiita.com/konojunya/items/d51672f900f4912a5563
https://blog.y-yuki.net/entry/2017/04/29/000000
スモウルビーで正三角形を描いてみる

スモウルビーで正三角形を描いてみます。

#1.正三角形の特徴
正三角形の特徴を確認します。
1.3つの辺の長さが等しい
2.3つの角度が等しい(60度=180÷3)
ですよね。カンタンカンタン。

#2.プログラミング
以下のように組み立ててみました。
![正三角形を描く(NG).png](https://qiita-image-store.s3.amazonaws.com/0/217329/19d24575-06fd-7a44-b9a8-623b482d8dd9.png)
ボールの方が中心がはっきりするので、キャラクターはボールにしています。

#3.実行
[実行]ボタンをクリックして描いてみます。
![60度ずつ角度を変えてみる.png](https://qiita-image-store.s3.amazonaws.com/0/217329/bb814243-6bea-7ee8-408d-0bbf9c5fafa0.png)
んー、これじゃない、、、三角形でもないし！

#4.なんで？
さっきのプログラムでは、100進んで、時計回りに60度回転なので、内角を60度にするのではなく、左から右へ線を描いて、進行方向に対して、図の黒いところの角度を60度回転したんですね。うーん、プログラムは命令どおりに動いている。ただ、考え方が足りませんでした。
![どこが60度変わったのか？.png](https://qiita-image-store.s3.amazonaws.com/0/217329/b53f0a40-de35-82e8-32d8-c124b50f4331.png)
内角を60度にしたい場合は、まっすぐな線(180度)から残したい角度(60度)を引いた残りだけ回転すればいんじゃない？なので、120度回転すればいけるハズ。

#5.プログラム修正
![正三角形を描く(OK).png](https://qiita-image-store.s3.amazonaws.com/0/217329/34ae0815-8998-ba4f-8609-38bacac442c4.png)
回転する角度を60度から120度に修正しました。

#6.実行
[実行]ボタンをクリックして描いてみます。
![描きたい正三角形.png](https://qiita-image-store.s3.amazonaws.com/0/217329/21484a70-a81b-7ee2-21b1-bb96a6dea7aa.png)
今度は、ちゃんと正三角形を描くことができました！
3回、同じことをしているんだから、繰り返しにするとか、つっこむところはありますが、ひとまず、おしまい。

#7.スモウルビーについて
スモウルビーは、
NPO法人Rubyプログラミング少年団
http://smalruby.jp/
で開発されています。無料で利用できます。
ブロックの組み立てでプログラムができます。
C＃でExcelにグラフィックを挿入する

Spire.XLSコンポーネントは、Excelに付属の幅広いカスタムグラフィックスをカバーする最大186のグラフィックタイプをサポートしています。 この記事では、Spire.XLSを使用してExcelドキュメントにグラフィックスを挿入し、グラフィックスにテキストを追加し、グラフィックスで色とイメージを塗りつぶす方法について説明します。
使用する必要のあるツール：[Spire.XLS for .NET](https://www.e-iceblue.com/Introduce/excel-for-net-introduce.html); Visual Studio.
【C#】

```ruby:Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Spire.Xls;
using Spire.Xls.Core;
using System.Drawing;

namespace Insert_shapes_in_excel
{
    class Program
    {
        static void Main(string[] args)
        {
            //ブックインスタンスを作成する
            Workbook workbook = new Workbook();
            //最初のワークシートを取得する
            Worksheet sheet = workbook.Worksheets[0];

            //三角形を追加し、その位置、幅、高さを指定する
            IPrstGeomShape triangle = sheet.PrstGeomShapes.AddPrstGeomShape(2, 2, 100, 100, PrstGeomShapeType.Triangle);
            //三角形を無地の色で塗りつぶす
            triangle.Fill.ForeColor = Color.Yellow;
            triangle.Fill.FillType = ShapeFillType.SolidColor;
            //テキストを追加
            triangle.Text = "テキスト";

            //心臓を追加し、その位置、幅、高さを指定する
            IPrstGeomShape heart = sheet.PrstGeomShapes.AddPrstGeomShape(2, 5, 100, 100, PrstGeomShapeType.Heart);
            //グラデーションで心臓を満たす
            heart.Fill.ForeColor = Color.Red;
            heart.Fill.FillType = ShapeFillType.Gradient;

            //デフォルトの色で塗りつぶす矢印を追加する
            IPrstGeomShape arrow = sheet.PrstGeomShapes.AddPrstGeomShape(10, 2, 100, 100, PrstGeomShapeType.CurvedRightArrow);

            //クラウドを追加し、その位置、幅、高さを指定する
            IPrstGeomShape cloud = sheet.PrstGeomShapes.AddPrstGeomShape(10, 5, 100, 100, PrstGeomShapeType.Cloud);
            //カスタム画像で雲を埋める
            cloud.Fill.CustomPicture(Image.FromFile("ピクチャ.jpg"), "ピクチャ.jpg");
            cloud.Fill.FillType = ShapeFillType.Picture;

            //ドキュメントを保存                       
            workbook.SaveToFile("シェイプを追加.xlsx", ExcelVersion.Version2013);
        }
    }
}

```
デバッグしてコードを実行すると、生成されたドキュメントが以下に表示されます:
![1.jpg](https://qiita-image-store.s3.amazonaws.com/0/278784/757525f9-b240-c4d1-efba-fb711748c161.jpeg)
ホームページのサーバー移転とhttps化を同時に実行した時の手順

# 状況
* ドメインはvalue-domainで独自ドメインを自分で管理している
* 月額5000円のブログシステム使用料を払っている
* httpなのでhttpsにするとさらに管理費を取られる

# 何をしたいのか
* ホームページを定評のあるエックスサーバーへ移行したい
* https化して安全な通信を行えるようにしたい
* ワードプレスに変えたい
* 現在稼働しているホームページは新ホームページができるまで稼働させたい
* 301リダイレクトをして恒久的に変更したい

# 何をやったか
## ワードプレスを簡単インストールする
同時にサイトが完成して旧ブログサービスを解約するまでワードプレス側で検索エンジンに引っかからないように設定しておく。ワードプレスの設定から表示設定に行って検索エンジンに引っかからないようにチェックボックスを外す。

## hostsファイルをサーバー宛に変える
編集して実際にページを見ようとすると今稼働しているホームページに飛ばされるので自分のコンピューターからだけはエックスサーバーに飛ぶようにする必要がある。管理者権限でメモ帳を開く必要があることに注意。以下の記事を参考のこと。

<https://qiita.com/fernet/items/cda95fe586a3613e30cf>

## htaccessに記述する
### 1. ドメインの正規化
サーバーにアクセスされたらどうすべきかを指示できるのがhtaccess記述。今回はhttpやwwwサブドメインでアクセスされたらhttpsに行ってもらいたい。以下のコードを# BEGIN WordPressの前につける。

1. RewriteEngine をOnにする
2. wwwサブドメインでアクセスされたらhttpsに変換する
3. httpでアクセスされてもhttpsに変換する


```
RewriteEngine On

RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]

RewriteCond %{HTTPS} !on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
```

### 2. ページごとに301リダイレクト記述
```
RewriteRule ^article/14109966.html$ https://mydomain.jp/about-invisalign/ [R=301,L]
```

※1　^はドメインを表すので古いページがディレクトリ配下にある場合には上記の `article/`は省略しない。
※2　スラッシュ(/)を先頭につける必要はない。^がスラッシュまで含んでいる。

### 3. ホームページを作成する
hostsで設定してあるので自分のPCからはエックスサーバーにつながるため地道に作る。ひたすら新しいページを作ってはhtaccessにページごとに301リダイレクト記述をしていく。それが終わったら内部リンクと画像の張替え、アイコンの作成を行って終了。あと、当サイトはGoogleMapを使っているのでAPI Keyを取得しワードプレス内の設定に記述。以下の記事を参照のこと。
https://nendeb.com/276


### 4. DNSレコード記述
ホームページが完成したら、いよいよDNS記述を変更することになる。Value-Domainにおけるネームサーバーが参照するDNSレコードのうち、Aレコードを書き換える。SSL指定したコモンネームをエックスサーバーのIPアドレスに変更する。今回はコモンネームはwwwサブドメイン付きドメインだったがdefaultとしてエックスサーバーのDNSで自動で設定されているwwwなしとワイルドカードも登録しておいた。

### 5. 待つ
24時間程度は待つこと。DNSの変更は時間がかかることで知られている。今回は12時間程度でDNS浸透が完了し、スマホからも見れるようになった。

### 6. google search consoleにhttpsも登録する。
サイトマップも作ってGoogle botに分かりやすく教える。Google Analyticsもhttpsに設定する。ワードプレスの検索エンジン回避のチェックを外す。Google botにクロールされ始めると気づかなかった404エラーを報告してくれる場合があるのでそのページを301リダイレクトする。

### 7. 旧ブログサービスを解約する



# 捕捉
SSL証明書に関して、エックスサーバーでは無料の証明書を発行できますが、これはDNSを変更しないと使えないため、CoreSSL（年額1000円）を契約しました。これでDNS変更前にhttpsのページを自分のＰＣから閲覧することが可能になります。
HDDからSSDへ換装

2011年から何の問題もなく使っていた富士通LIFEBOOKAH77/D。しかし2018年9月13日あたりに一気に重くなり、Google Chromeの起動にたっぷり5分はかかる有様、Jupyter notebookも「一体どれだけ待てばよいのか」な待ち時間になったので、かねてより気になっていたHDDからSSDへの換装をしました。

# 使ったもの
- 2011年製富士通LIFEBOOKAH77/D
- [intel SSD5 360GB](https://amzn.to/2QAQHWE)
- [2.5インチポータブルハードディスクケース](https://amzn.to/2xifAyr)
- [HD革命/CopyDrive Ver.7](https://amzn.to/2xgVMvj)

換装した日: 2018/09/16

# 参考にしたサイト
[ノートパソコンのHDDをSSDに換装する方法](https://www.at-mag.co.jp/hdd_ssd.html)

# 所要時間
正確には計っていませんが、20時間以上24時間未満、というところでしょうか。リカバリディスクを作っていなかったので、リカバリディスク作成にも時間を割きました。一番時間がかかったのはCドライブのコピーで、ここでたっぷり20時間かかりました。

#ハラハラした瞬間
- [2.5インチポータブルハードディスクケース](https://amzn.to/2xifAyr)が開かなかったとき
- 「C, Dドライブをコピーします」の表示とともに「計600GB超」とあったとき。
- SSD換装後初起動で富士通ロゴのまま5分ほど時間が経過したとき。
- SSDのフォーマットでSSDをFドライブに指定していたが、いつの間にかHドライブとして認識されていたとき。


私ではハードディスクケースが開かず父に頼んで開けてもらいました:man: 
「計600GB超」。。。「私、買ったの360GBなのにー!」とパニックになりかけましたが、DドライブにコピーしていたCドライブの中身を全消去、再起動して再度トライ。しかし「計600GB超」の表示は代わらなかったので、「Dドライブは何もないはずだから!」と強行突破。問題なくコピーできました:+1:

**SSD換装後初起動で富士通ロゴのまま5分ほど時間が経過** この瞬間が一番ハラハラしていました。「1時間待ってダメだったらBIOSやBootの設定に行こう」の心境でした。しかしこれはSSD換装後初起動のときのみで、次の起動からはすぐに立ち上がるようになりました。:elephant:果報は寝て待て:elephant:

# 使わなかったHDDの使い道
Lunuxを入れて遊ぼうと思います。

# 「これいらなかったな」と思うもの
DドライブへのCドライブのコピー。SSDへのコピーには入りきれず(当然)。

# 次また換装をやるとしたら?
リカバリディスク (DVD-R 4.5GBを6枚使用) は前もって作っておくこと。今回はぎりぎり空のものが6枚あったが、やはり作るのはパソコンを新調したタイミングだよな、と思いました。
SSDやディスクケースの調達は最初EDIONに行ったのですが、「内蔵用のSSDはないんですよね」と言われ、最終的にアプライドで調達しました。次はもうアプライド一択で。

# 換装後の挙動
めっちゃ速いです! やってよかった! 起動もソフト立ち上げもかなり速くなりました:penguin:
[Python] POSTされたmultipart/form-dataをFieldStorageでパースする

フロントエンドから**ファイルをmultipart/form-data形式でPOST**するためのWeb APIをサーバーレスで開発していて、データの取り出しに少しハマって調べたので書いておきます。

# multipart/form-data
multipart/form-dataは、**一回のPOSTリクエストで複数のデータやファイルをサーバーに送信する**ときに使うリクエストヘッダーです。
それぞれのファイルやデータを**boundary**という文字列で区切ってリクエストボディに入れます。boundaryは多くのWebリクエストクライアントで自動的に生成してくれます。

curlを使ってmultipart/form-dataをリクエストする場合は下記のようになります。

```bash

curl -X POST http://localhost:3000 \
-F "data=@/path/to/sample.txt;type=text/plain" \
-F "csvdata=@/path/to/HelloWorld.csv;type=text/csv"
```

リクエストボディはこんな感じになります。

```
--------------------------5534b722b1776e54
Content-Disposition: form-data; name="data"; filename="sample.txt"
Content-Type: text/plain

This is Sample Text!!

--------------------------5534b722b1776e54
Content-Disposition: form-data; name="csvdata"; filename="HelloWorld.csv"
Content-Type: text/csv

foo,bar,baz
hoge,piyo,moge

--------------------------5534b722b1776e54--
```
boundaryは`--------------------------5534b722b1776e54`の部分です。
ボディデータ内のどれがboundaryなのかをサーバーに教えて上げる必要があるのでヘッダーにその情報が入っています。

```
{'Content-Type': 'multipart/form-data; boundary=------------------------5534b722b1776e54'}
```

このヘッダー情報を使ってデータをパースしていく処理を自前で実装するのめちゃ大変・・・。

調べたところ**FieldStorage**を使ってねということでした。

# FieldStorage
FieldStorageはPython標準ライブラリに含まれる**cgi**モジュールのクラスです。FieldStorageにリクエストボディとヘッダー情報を引数として渡すと、下記の情報が取得できます。

- フィールド名（リクエスト時の`curl ... -F data=@hoge.txt`の`data`の部分）
- ファイル名（例：`hoge.txt`）
- ファイルタイプ（例：`text/plain`）
- データ（例：`hello world`）

## FieldStorageに渡す引数
#### fp
fpは`file pointer`のことで、ボディ本体を渡します。渡すボディは`TextIOWrapper`クラスのオブジェクトである必要があるので`io.BytexIO()`で読み込みます。今回の場合はリクエストボディデータがBase64エンコードされた状態で送られてくるのでBase64デコード処理も入れています。

#### headers
**content-type**と**content-length**を渡します。リクエストで受け取ったヘッダーは`Content-Type`や`Content-Length`になっていて、それをそのまま渡すとFieldStorageクラス内で読み込めないため、キーをlower caseにしてあげてます。（ここでめっちゃハマった・・）

#### environ
これはPOSTメソッドの操作だよと、**REQUEST_METHOD**に入れてあげる必要があります。

## コード
最終的にはこのような形になりました。 `fs.list`をfor文で回して、それぞれのデータを取り出して処理しています。

```python

import base64
import io
from cgi import FieldStorage

def parse_multipart_form(headers, body):
    fp = io.BytesIO(base64.b64decode(body))
    environ = {'REQUEST_METHOD': 'POST'}
    headers = {
        'content-type': headers['Content-Type'],
        'content-length': headers['Content-Length']
    }

    fs = cgi.FieldStorage(fp=fp, environ=environ, headers=headers)

    for f in fs.list:
        print(f.name, f.filename, f.type, f.value)
```

## 出力

```
data sample.txt text/plain b'This is Sample Text!!\n'
csvdata HelloWorld.csv text/csv b'foo,bar,baz\nhoge,piyo,moge\n'
```


---
以上です。

今回はFieldStorageをこういう使い方をしている例があまり見つからず、cgiのコードを読み込みました。いい勉強になります。

本当は、せっかくサーバーレスのようなクラウドネイティブなアプリケーションを構築しているのであれば、フロントからのファイルアップロードは、S3に直接アップロードするほうがいろいろと楽ですよね。


最後に、

- API Gatewayを使うのであればバイナリサポートを有効にすること
- Lambdaファンクションに渡せるイベントデータの上限は6MB

この部分は原因の発見が難しいので要注意です。
コードの命名規則①

今関わってるプロジェクトのコード命名がめちゃくちゃ綺麗なので、知見を深めようと思いリーダブルコードを読んだ。
初心者とかはすごく参考にした方が良い良書です。

## 名前に情報を詰め込む
・明確な単語を選ぶ
  例えば、Getではなく状況に応じてFetchやDownloadを使う
 
・tmpやretvalなどの汎用的な名前を避ける
  ただし明確な理由があれば別

・具体的な名前を使って、物事を詳細に説明する
  ServerCanStart()よりもCanListenOnPort()の方が明確で良い

・変数名に大切な情報を追加する
秒、ミリ秒などの単位がつくものには _s, _msを後ろにつける
これからエスケープが必要な場合は、 raw_をつける

・スコープの大きな変数には長い名前をつける
これはプロジェクト全体に影響するものは長くてもわかりやすい名前をつけた方がいいよということ
逆にスコープが小さい場合は単語並みに短いもので良い

・大文字やアンダーバーなどに意味を込める
クラスメイとローカル変数を使い分けたりなどなど

## 他の人(数ヶ月後の自分かも)が誤解されないようにする
・filter,limit,lengthのような曖昧な単語は極力使わない

・上下の限界値を決める際は、 max_ min_ などを使うと良い

・包含的範囲であれば、first_ last_ を使うと良い

・包含/排他的範囲であれば、 begin end を使うと良い

・プール値を使う際は、　is_ has_ などの単語を使う

.disable_のように否定形は極力避ける

## 美しいネーミングにする
・読み手が慣れているパターンと一貫性のあるレイアウトを使う
・似ているコードは似ているように見せる
・関連するコードはまとめてブロックにする

`プログラミングをする時間はほとんどがコードを読む時間なのだ！`

・コードに一貫性を持たせる

```
#悪い例
exampleA = new example_example_example()
  exampleA = 
    new example_example_example()
  exampleA = new example_example_example()
#良い例
exampleA = 
　　new example_example_example()
exampleA =
　　new example_example_example()
exampleA = 
　　new example_example_example()
```

・複数のコードブロックで同じようなことをしていたら、シルエットも同じようにする

・コードの列を整列すれば、一段とコード全体が見やすくなる

・ある場所でABCと並べていたものをBCAのように並べてはいけない。意味のある順番を抜擢する

```
#悪い例
a = "朝の挨拶は"
c = "という"
b = "おはようございます"
#良い例
a = "朝の挨拶は"
b = "おはようございます"
c = "という"
```

・空行を使って大きなブロックを論理的な「段落」に分ける

## コメント
・なぜコードが他のやり方ではなくこう書かれているのか
・コードの欠陥を以下の表記を例に書き記す

```
・TODO: ~  あとで手をつける 
・FIXME: ~ 既知の不具合があるコード
・HACK: ~ あまり綺麗じゃない解決策
・XXX: ~ 危険！大きな問題あり
・maybe-later: ~ あとで修正する
```

・定数の値にまつわる「背景」
・読み手(他の人)の立場になって考え、質問されそうなことをコメントにして、コメントとコードを見れば大まか理解できるようにする

・コメントでは「それ」「あれ」などの代名詞は避ける

・関数の動作はできるだけ正確に

・コードの意図は詳細レベルではなく、高レベルで記述する

・多くの意味が詰め込まれた言葉や表現を使って簡潔に記述する

## まとめ
普段から綺麗に描こうと努力していたものの改めて見直すと雑なところがあったかもな...。
大変いい学びになった。

随時追記していきます><
いまさら始めるJava8 ～Optional～

第1回：[いまさら始めるJava8 ～forEachとラムダ式～](https://qiita.com/uchi_y/items/b292e231b0fe3c6032ee)
第2回：[いまさら始めるJava8 ～StreamAPI～](https://qiita.com/uchi_y/items/dfe227612269dccf611c)
第3回：[いまさら始めるJava8 ～日付時刻API～](https://qiita.com/uchi_y/items/8de08b569378e3245f63)

Optionalとは、null以外の値を持つかもしれないし、持たないかもしれないものを扱うクラスです
`Optional<String> `は何か文字列を持つかもしれないし、持たないかもしれないという型です

# Optionalの生成

## 値を持たない
```
Optional emptyCase = Optional.empty();
```
空のOptionalを生成します
## 値を必ず持つ
```
Optional presentCase = Optional.of("example");
```

値を持つOptionalを生成します
引数にnullを渡した場合、NullPointerExceptionが発生します

## 値を持つかもしれないし、持たないかもしれない
```
Optional nullableNullCase = Optiona.ofNullable(null);
Optional nullableNotNullCase = Optiona.ofNullable("example");
```

引数がnullであれば空のOptionalを、そうでなければ引数の値を持つOptionalを生成します

# Optionalの利用
## 値があるか判定する
### isPresent
値を持つ場合はtrue, 持たない場合はfalseを返します

```
Optional presentCase = Optional.of("example");
presentCase.isPresent();  // true

Optional emptyCase = Optional.empty();
emptyCase.isPresent();  // false
```
### ifPresent
値を持つ場合は引数のConsumerを値を引数にとって実行し、持たない場合は何もしません

```
Optional presentCase = Optional.of("example");
presentCase.ifPresent(s -> {System.out.println(s)});  // 標準出力に"example"と出力

Optional emptyCase = Optional.empty();
emptyCase.ifPresent(s -> {System.out.println(s)});  // 何もしない
```

## 値を取得する
### get
値を持つ場合はその値を返し、値を持たない場合は`NoSuchElementException`がthrowされます

```
Optional presentCase = Optional.of("example");
presentCase.get();                    // example

Optional emptyCase = Optional.empty();
emptyCase.get();                      // NoSuchElementException が発生
```
値を持つことを期待している場合に使います
値を持たない場合にデフォルト値を使いたい場合は次の`orElse`を使ったほうがよいです

### orElse
値を持つ場合はその値を返し、値を持たない場合は引数で指定した値を返します

```
Optional presentCase = Optional.of("example");
presentCase.orElse("default");                    // example

Optional emptyCase = Optional.empty();
emptyCase.orElse("default");                      // default
```

### orElseGet
値を持つ場合はその値を返し、値を持たない場合は引数で指定したSupplierの結果を返します

```
Optional presentCase = Optional.of("example");
presentCase.orElseGet(() -> {"default"});          // example

Optional emptyCase = Optional.empty();
emptyCase.orElseGet(() -> {"default"});           // default
```
`orElse`との違いは、デフォルト値を直接渡すかラムダ式で表すかです

### orElseThrow
値を持つ場合はその値を返し、値を持たない場合は引数で指定したSupplierで例外をthrowします


## 値を利用する

### map
値を持つ場合は引数のマッピング関数をその値に適用し、結果がnullでなければ結果を記述するOptionalを返します。それ以外の場合は空のOptionalを返します

```
Optional<String> presentCase = Optional.of("example,1,exp");
Optional<String[]> result = presentCase.map(name -> name.split(",")); // [example, 1, exp]

Optional<String> emptyCase = Optional.empty();
Optional<String[]> result = emptyCase .map(name -> name.split(",")); // 空のOptional
```

### filter
StreamAPIのfilterと同じような働きをします
引数のラムダ式の条件に一致する場合は元のOptionalを返し、そうでない場合は空のOptionalを返します

```
Optional<String> presentCase =Optional.of("example");
Optional<String> match = presentCase.filter(exp -> exp.length() == 7); // "example"

Optional<String> notMatch = presentCase.filter(exp -> exp.length() != 7); // 空のOptional
 ```
Google ColaboratoryでGPUを使おうとすると「バックエンドを割り当てられませんでした」と言われる時

# 問題
Google ColaboratoryでハードウェアアクセラレータにGPUを選択したランタイムを立ち上げようとすると、
*「バックエンドを割り当てられませんでした」*
と表示され、GPU無しのランタイムしか立ち上げられない。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/233586/0ef8b0ee-dfa7-d8ed-d2b3-b2acc8b3f5eb.png)

# 解決策
結論から言うと、**自分で出来ることは何も無く、待つしか無い。**
googleが用意しているGPUリソースが全て使用中の場合にこのエラーが出るらしく、世界のどこかで誰かがリソース使用をやめるまでは使えるようにならない。
どのくらい待つ必要があるのかはタイミングによるのだろうが、この記事を書いている2018/09/17日 AM9:00~10:00の一時間では使用できるようにならなかった。

もし自前で高性能GPU入りのPCを用意できるなら、そちらに環境構築した方が待ち時間が発生せず良いのかも知れない。
JavaScriptのいけてない要素(ver 1.00)

#JavaScriptは猛省すべき

JavaScriptと関わって丸3年。
中級者になったくらいの気分。
うっかりはまった落とし穴を記す。
後続の人はよく避けられたい。

---
#ES6は妥当

## ReferenceError: * is not defined
* コールバック関数中のthisで
  * 原因: コールバック関数が異なるスコープであり、thisが切り替わってしまうため
  * ES6で解決: アロー関数: ()=>{}
  * 反省点: **bindしたりしなかったりの記述の不統一さ**や、**よく使う式なのに記述タイプ量が多いこと**

従来の書き方では、引数で渡すかbindしていた。あるいは冒頭にvar self = this; とか。

```javascript
arr.forEach(function(){}, this)
arr.reduce(function(){}.bind(this), initialValue)
```

なお、引数リスト内で分割代入ができるらしいが、使えて便利な頻度はどれくらいか?
>// 引数リスト内の分割代入もサポートしています
>var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
>f();  // 6

* 連想配列のループで
    * 原因: for-inループはenumerableなプロパティを拾うため
    * ES6で解決: for-of, Map
    * 反省点: **仕様の矛盾でしょう**

従来の書き方では、意図通りに使うにはObject.keys()を使う必要があった。

```javascript
Object.keys(hash).map(function(key){val = hash[key]; ...})
```

基底のObjectをそう簡単に拡張するなよ、と思う向きもあるかもわからんが、Objectの備える基礎メソッドが貧弱だから追加せざるをえないという。[for...of](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/for...of)を見よ。

```javascript:Object.keys(hash)ではなくhash.keys()にするには
Object.defineProperty(Object.prototype, 'keys', {
  enumerable: false,
  value: function() {
    return Object.keys(this);
  }
});
```

ただ、for-ofはargumentsやNodeListなどもループで回せるから改善されたように思えるが、文法要素を増やす対応が適切かは個人的には疑問。コンパイラの修正・検証・最適化に対する指示を考えると。

---
# パッケージで解決

 * 文字列へのフォーマット関数sprintf()
 
---
# prototypeに追加せざるを得ない
## Array.prototype._push():Array

* ループ中に除外する場合、記述が定型的に冗長になる
    * 原因: Array.prototype.push()の戻り値がlength

```javascript
var result_caseofinloop = arr.reduce(function(acc, val){  
  if(cond)
    acc.push(f(val));
  return acc
}, [initialValue])

// そうではなく短く書きたいねん
var result_caseofinloop = arr.reduce((acc,val)=>{
　return cond ? acc._push(f(val)): acc
}, [initialValue])

// otherwise 除外してループというやり方もある。
// initialValueがなければいいけどな。unshiftも結果配列のlength返すという、、、もー。
var result_caseofbeforeloop = arr.filter(cond).map((val)=>{return f(val)}
result_caseofbeforeloop.unshift(initialValue);
// 性能的にどうなんやろ？
//
```

## Object.prototype._assign(key, val): Object
* ループ中の記述が定型的に冗長になる
    * 原因: 代入式の戻り値が右辺だから

```javascript
// hashのキーでループ

var result_caseofinloop = Object.keys(hash).reduce(function(acc, key){
    acc[key] = f(hash[key])
  return acc
}, initialValue)

// 短く書きたいねん
var result_caseofinloop = hash.keys().reduce((acc, key)=>{
  return acc._assign(key, f(hash[key]))
}, initialValue)
// 除外条件付きなら、keys(cond)にするのも手やな。
var result_caseofinloop = hash.keys(cond).reduce((acc, key)=>{
  return acc._assign(key, f(hash[key]))
}, initialValue)
```