OmniAICreator/Qiita-1.07M huggingface dataset:
npmのアプリケーションをyarnに移行する

## 概要

npmよりもyarnの方が高速らしいので、npmからyarnに移行してみる。

## 手順

### yarnコマンドを使えるようにする

```
# npm install -g yarn
/usr/local/bin/yarn -> /usr/local/lib/node_modules/yarn/bin/yarn.js
/usr/local/bin/yarnpkg -> /usr/local/lib/node_modules/yarn/bin/yarn.js
+ yarn@1.7.0
```

macOSでは `brew` でインストールしたり、RedHat系ディストリビューションLinuxでは `yum` でインストールできる。

他のインストール方法も[Yarnの公式Installation](https://yarnpkg.com/en/docs/install#mac-stable)に記載されている。

package.jsonがある、アプリケーションのディレクトリで作業を行う。
↓確認のコマンド

```
# ls -1 ./ | grep package.json
package.json
```

`yarn` コマンドを実行して、アプリケーションでyarnを使えるようにする。

```
# yarn
yarn install v1.7.0
info No lockfile found.
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
Done in 118.27s.
```

↑これで
カレントディレクトリに `yarn.lock` が作成される。
↓確認のコマンド

```
# ls -1 ./ | grep yarn.lock
yarn.lock
```

これでyarnコマンドが使えるようになった。

### yarnコマンドを使ってみる

パッケージをインストールする。

```
# yarn install
yarn install v1.7.0
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
Done in 71.00s.
```

`npm install` を実行したときと同じく `node_modules` にパッケージがインストールされる。

```
# yarn run dev
yarn run v1.7.0
```

他のnpmコマンドもyarnで実行できる。
↑は `npm run dev` で実行していたコマンドを `yarn run dev` で実行したみた。

## 検証環境

Amazon Linux 1です。

```
# cat /etc/system-release
Amazon Linux AMI release 2017.09
```
C言語 フォルダ作成

#フォルダ作成
```c
#include <stdio.h>
#include <direct.h>

void main(){

	if (_mkdir("c:\\Newfolder") == 0)
		printf("フォルダを作成しました。\n");

	else
		printf("フォルダ作成に失敗しました。\n");

}
```

#実行結果

```
フォルダを作成しました。
```
```
フォルダ作成に失敗しました。
```
Basic認証とIP制限を設定して、Nginxサーバーのセキュリティを高める

## 動作環境
```shell-session:~
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.4 LTS"
$ nginx -v
nginx version: nginx/1.14.0
```
## Basic認証の設定
Basic認証はもっとも簡単なパスワード認証の一つです。ほぼ全てのブラウザに対応しており、認証用画面を作成することなくパスワード認証を行うことができます。nginxでは、デフォルトで組み込まれているngx_http_auth_basic_moduleを使用してBasic認証を利用できます。

Appacheに付属しているhtpasswdコマンドを使ってパスワードファイルを生成します。

```shell-session:~
sudo apt install apache2-utils

sudo htpasswd -c /etc/nginx/.htpasswd username #任意のユーザ名を記入
New password:  #任意のパスワードを入力
Re-type new password:
Adding password for user username
```
nginxの設定ファイルに以下を付け加えます。
auth_basic：basic認証の認証領域名を指定し、basic認証を有効にする
auth_basic_user_file：basic認証のユーザ名とパスワードを記述したファイルを指定します。


```nginx:/etc/nginx/nginx.conf
http {
 #Basic認証
    auth_basic "basic-test";
    auth_basic_user_file /etc/nginx/.htpasswd;
}
```
nginxを再起動して、設定ファイルを読み込ませます。

```shell-session:~
$ sudo systemctl restart nginx.service
```

## IP制限
サーバー単位でアクセスの制限を行う場合は、

```nginx:/etc/nginx/conf.d/default.conf
server {
    allow ***.***.***.***; #アクセスを許可するIPアドレス
    deny all;
}
```
ディレクトリごとのアクセス制限は、

```nginx:/etc/nginx/conf.d/default.conf
location /制限先ディレクトリ/ {
    allow ***.***.***.***; #アクセスを許可するIPアドレス
    deny all;
}
```


**おまけ**
nginxのバージョン情報が表示されないようにする。

```nginx:/etc/nginx/nginx.conf
http {
 # version off
    server_tokens off;
}
```
設定ファイルの書き込みが終わったら、nginxを再起動します。

```shell-session:~
$ sudo systemctl restart nginx.service
```
daemonize

# やりかた

* fork
親プロセスは終了

* setsid で端末を切り離す 
* カレントディレクトリを / にする。
* stdin, stdout, stderrをクローズ


簡易版

```````C
void daemonize(){
   switch (fork()) {
    case -1:
        return (-1);
    case 0:
        break;
    default:
        exit(EXIT_SUCCESS);
    }

    if (setsid() == -1)
        return (-1);

    if (nochdir == 0) {
        if(chdir("/") != 0) {
            return (-1);
        }
    }
  // reset mask
  umask(0);
  close(STDIN_FILENO);
  close(STDOUT_FILENO);
  close(STDERR_FILENO);
}
デュアルディスプレイ間でアプリ表示を移動するショートカット（備忘録）

# デュアルディスプレイ間でアプリ表示を移動するショートカット

## 環境

Windows10

## 概要

Slackアプリを使っているのですが、ラップトップPC＋ディスプレイで使っていて、打合せなどで
ディスプレイを切り離すと、Slackアプリは、ディスプレイ側に表示していた場合ラップトップPC
側に移動する術がなくなってしまいます。

通常のアプリの場合は、タスクバーのアプリのポップアップを右クリックして、「移動」を選んで方向キーでウィンドウの移動ができますが、Slackアプリはこの操作が表示されません。

そこで、Windowsショートカット。

[Shift]+[Windowsキー]+[方向キー]　（左、右）

便利ですが忘れてしまうので、備忘録として。
PythonでSPIデータを用いてt検定を行う方法

この記事に書いてある内容は、私が所属する会社とは一切関係がありません。
また近くにコードレビューしてくれる方も、見せる人もいないのでFBなどくださるとありがたいです。

## 目的
社員を便宜的にハイパフォーマーとローパフォーマーに分類し、SPIの言語・非言語スコアや性格特性に有意な差があるかをPythonの[scipy.stats.ttest_ind](https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.ttest_ind.html)を用いて調べました。

## 結論
ハイパフォーマーの定義によりますが、有意な差がある項目がいくつか現れました。以下のようなoutputが得られます。

```python
Column Name: imagination, T Value=[1.46385011], P Value=[0.2394426]
Column Name: introvert, T Value=[-3.91918359], P Value=[0.02954136]
Column Name: nonverbal_score, T Value=[4.79319137], P Value=[0.01727471]
Column Name: verbal_score, T Value=[0.77459667], P Value=[0.49502535]
```

架空のデータセットですが、outputを見ると内向性と非言語スコアは有意な差がありそうです。

## 実施方法
### 環境
- windows
    - 会社のpcなので詳しくは調べていません
- Anaconda 5.2

ライブラリは以下をimportしておきます。

```python
import numpy as np
import pandas as pd
from pandas import DataFrame, Series
import scipy.stats as stats
```

### ダミーデータを用意する
まずは架空のデータセットを作り、ハイパフォーマー（hp）とローパフォーマー（lp）にデータフレームに分割します。

```python
data = {
    'hp':              [0, 0, 0, 1, 1],
    'verbal_score':    [53, 54, 53, 53, 55],
    'nonverbal_score': [53, 54, 53, 60, 65],
    'imagination':     [50, 51, 51, 52, 51],
    'introvert':       [53, 50, 51, 45, 47]
}

spi_frame = DataFrame(data)

# dataframeを分割する
hp = spi_frame[spi_frame.hp == 1]
lp = spi_frame[spi_frame.hp == 0]
```

### 一列ごとにt検定を行う

```python
ttest_result = stats.ttest_ind(hp.nonverbal_score, lp.nonverbal_score)
ttest_result

# output
Ttest_indResult(statistic=4.793191373636545, pvalue=0.017274707950747335)
```

### 全てのColumnで一度にt検定を行う
上記の方法でもt検定を行えますが、全ての結果を一列ずつt検定するのは疲れるのでfor文で一気に行います。そのコードが以下です。

```python
for i in range(1, len(spi_frame.columns)):
    t, p = stats.ttest_ind(hp.iloc[:, [i]], lp.iloc[:, [i]])
    name = spi_frame.columns.values[i]
    print('Column Name: {}, T Value={}, P Value={}'.format(name, t, p))

# output
Column Name: imagination, T Value=[1.46385011], P Value=[0.2394426]
Column Name: introvert, T Value=[-3.91918359], P Value=[0.02954136]
Column Name: nonverbal_score, T Value=[4.79319137], P Value=[0.01727471]
Column Name: verbal_score, T Value=[0.77459667], P Value=[0.49502535]
```

## 補足
差が有意にある項目だけ知りたい場合は、if文を使ってp < 0.05とかにしておけば見やすくなります。

## 参考
- [SPI総合検査](https://ja.wikipedia.org/wiki/SPI%E7%B7%8F%E5%90%88%E6%A4%9C%E6%9F%BB)
- [t検定](https://ja.wikipedia.org/wiki/T%E6%A4%9C%E5%AE%9A)
CEDEC2018個人的にきになるものメモ

#■全般
「どこから作ればいいんだろう？から１０年」（仮）
08月22日(水) 09:45 〜 11:05

メディアが語るインディーゲームPR術 「つくって半分、知ってもらって半分」
08月24日(金) 11:20 〜 12:20


#■JavaScript,WebGL
JavaScriptとWebGLで圧倒的な3D空戦バトルを再現。「編隊少女 -フォーメーションガールズ-」における3Dレンダリング技術解説 ～Babylon.jsとBISHAMON WebGL版の合成～
08月22日(水) 16:30 〜 17:30

HTML5ゲームの新しい潮流と開発手法
08月24日(金) 11:20 〜 12:20

HTML5メッセンジャーゲームのクロスプラットフォーム対応手法
08月24日(金) 13:30 〜 14:30

WebAssembly による HTML5 ゲーム開発
08月24日(金) 15:20 〜 15:45

真のリアリティを実現するクロノスのオープンスタンダードAPI: WebGL, glTFを中心に主要API最新情報ご紹介
08月24日(金) 17:50 〜 18:50

時代とともに変わるゲームアプリのテスト～不当表示対策編～
08月23日(木) 15:20 〜 15:45



#■開発手法、プロジェクト管理
新規ゲーム立ち上げ時にUI・UX特化エンジニアをアサインするべき理由 〜戦姫絶唱シンフォギアXD UNLIMITEDにおけるUI作成の高速なワークフロー〜
08月23日(木) 11:50 〜 12:15

オートプレイによるレベルデザインシミュレーション〜自動化時代のゲームフレームワークに求められること〜
08月22日(水) 17:50 〜 18:50

ワンランク上のゲームデザイン・レベルデザイン・UIデザインを考える 「コンテキスト」「コンフリクト」「コントラスト」デザイン
08月23日(木) 11:20 〜 12:20
美しく生命力あふれるチーム ～ 1時間から始めるアジャイル ～
08月22日(水) 16:30 〜 17:30

スクラム、モブプロ、アジャイルエンタープライズ ー 小さなチームと大きな組織
08月22日(水) 17:50 〜 18:50

機能横断チームでアプリを効率よく開発しよう！
08月24日(金) 13:30 〜 13:55

チームの成果を上げるためのコミュニケーション・スキル
08月23日(木) 10:00 〜 11:00

「Ｄ×２ 真・女神転生リベレーション」におけるアニメーション制作事例〜184体の魅力ある悪魔アニメーションを少人数＋アウトソーシングで短期間で制作するヒント～
08月22日(水) 16:30 〜 17:30

ゲーム制作のプロジェクト管理における「ディベロッパー」と「パブリッシャー」の連携について



#■育成
若手テクニカルアーティストの育成とその役割について話すラウンドテーブル
08月23日(木) 10:00 〜 11:00

中堅人材育成プログラム「VIRTUAL無茶振り道場」
08月24日(金) 13:30 〜 14:30


#■機械学習、AI
モバイルゲームのお問い合わせ対応にてAIチャットボットを導入してお問い合わせ件数を約20%削減した話
08月23日(木) 14:50 〜 15:15

パネル：ゲーム開発における、機械学習の応用。開拓者は要望・方向性・工夫を語る～
08月24日(金) 17:50 〜 18:50

モバイルタイトルにおける横断的な機械学習によるレベルデザイン支援システムの構築と運用
08月22日(水) 11:20 〜 12:20

アプリ改善を深化するデータ分析 〜現場で使えるデータを片っ端から可視化するコツ〜
08月22日(水) 13:30 〜 14:30

データを分析する文化を作る-開発運営が自分でデータを分析してもらうためにしたこと-
08月22日(水) 16:30 〜 17:30

TCGのバランシングを解剖する―機械学習を用いた開発運用の効率化について―
08月23日(木) 14:50 〜 15:15

AIによる汎用的バランス調整とその可視化: グリムノーツRepage PvPの事例
08月23日(木) 16:30 〜 17:30

ビッグデータ、機械学習、ビデオゲーム: 各プレイヤーの行動を予測する　Big data, machine learning and video games: predicting individual player behavior
08月23日(木) 16:30 〜 17:30

スマートなアンチチート: 機械学習を利用してプレイヤーの楽しみと利益を保護する　Smart Anti-Cheat: Using Machine Learning to protect your fun and profit
08月22日(水) 17:50 〜 18:50




#■海外
ベトナムオフショアによるソーシャルゲーム開発・運用事例の紹介 〜15プロダクトを4年間運用して見えてきた利点と課題〜
08月22日(水) 11:20 〜 12:20

続：Ubiサンフランシスコ x 大阪 ～米日共同開発の現場最前線より 答え合わせ編
08月22日(水) 13:30 〜 14:30
X68000 XVI > 電源基板 > Link > 入手性の良い代替IC (2018年7月) | 5DL2CZ41A | その他IC情報

```txt:動作環境
X68000 XVI
```

### 関連

- [X68000 XVI > 電源基板 > R24 > 回路図には記載はあるが未実装 > 回路図が古い?](https://qiita.com/7of9/items/877258388bc6db7317fe)

## 入手性の良い代替IC

1988年ごろのX68000 XVI。搭載ICは当然古い。

2003年頃から数年程度の間の修理情報も検索すると見つかるが、2018年現在ではそれらに記載されるICの入手性もものによっては難しいかもしれない。

2018年7月現在、どのような代替ICが入手しやすいだろうか。

下記に整理されているのを見つけました。

### リンク1

- かおる 様
    - [使用部品の互換情報について その1](http://js1dsr.sblo.jp/article/181139689.html)
    - [使用部品の互換情報について その2](http://js1dsr.sblo.jp/article/181233465.html)

情報感謝です。

> D23：東芝 5DL2CZ47A(高速高効率ダイオード)

サービスマニュアル（後述）の回路図では「5DL2CZ41A」という型番のようです。

### リンク2

- Makoto Kamada様
    - [ツイート](https://twitter.com/kamadox/status/998777091159031808)

情報感謝です。

- 11EFS2の代わりとしてのBYV27-200-TR
    - [@ Digikey](https://www.digikey.jp/product-detail/ja/vishay-semiconductor-diodes-division/BYV27-200-TR/BYV27-200CT-ND/3104386) 

### 2002年(2006年最終更新)の情報

別途、下記は2002年の情報ですが、今でも有用な情報がたくさん記載されていると思われます。

- 永井良晴 様
    - [X680x0 電源装置を斬る!](http://x68k.net/x68dengen/)

情報感謝です。

### サービスマニュアル

下記の資料も参考にします。

- SHARP サービスマニュアル X68000 パーソナルコンピュータ CZ-634C-TN, CN-644C-TN
    - COCORO Booksにて閲覧可能

@ サービスマニュアル
p97 22. 電源基板基本配線図
p99 23. 電源基板

「電源基板基本配線図」の方は回路図のようだ。
「電源基板」の方では、基板の実装パターンが閲覧可能。
Pythonで世界地図-19(世界の町のシェープファイルを取得)

参考
 osmnx/osmnxTest.py
https://github.com/smnra/osmnx/blob/master/osmnxTest.py

```python:get_city_shp.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-

import osmnx as ox
import matplotlib.pyplot as plt
import sys

args = sys.argv
argc = len(args) # 引数の個数

if (argc != 2):   # 引数がない場合
    print ('./get_city_shp.py 目的地の名称')
    quit()


cityName = args[1] #'HigashiOsaka','tokyo,Japan'
city = ox.gdf_from_place(cityName)
city.plot()

ox.save_gdf_shapefile(city,cityName,'./data') #dataフォルダに保存

plt.show()
```

$ ./get_city_shp.py HigashiOsaka

![image.png](https://qiita-image-store.s3.amazonaws.com/0/238800/e12d11fe-a9cb-a376-6779-befa2643221c.png)

実行したフォルダのdataフォルダにHigashiOsakaフォルダが作成され、
HigashiOsaka.cpg  HigashiOsaka.prj  HigashiOsaka.shx
HigashiOsaka.dbf  HigashiOsaka.shp
が保存される。

引数cityNameの例
HigashiOsaka
Tokyo,Japan
雁塔区,西安,中国
"Manhattan, New York, USA"
引数にスペースが含まれる場合は、コーテーションマークで括る
#####上記で取得したシェープファイルを利用する

```python:
#!/usr/bin/python3
# coding: UTF-8

from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import japan_border2 as jb2 #都府県境界線

font = {'family': 'IPAGothic'}  # 日本語Fontを指定

lon1 = 135.50
lat1 = 34.5
lon2 = 1.0
lat2 = 1.0

map = Basemap(llcrnrlon=lon1-lon2,llcrnrlat=lat1-lat2,urcrnrlon=lon1+lon2,urcrnrlat=lat1+lat2,resolution='i',projection='cyl')

map.drawcoastlines() #海岸線

jb2.prefectural_bound(map = map) #都府県境界線

map.readshapefile('/home/ty/python/map/OSMnx/data/HigashiOsaka/HigashiOsaka', 'counties', color ='m')

lon = 135.6009
lat = 34.6793
plt.plot(lon, lat, 'ro', markersize=2, color='red')
plt.text(lon, lat, " 東大阪市役所", fontsize=12, color='red', **font)

print(map.counties)

plt.show()

```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/238800/7f5a2ad1-94ea-1c6a-a624-9f3afd456c98.png)
従来のCAM環境とfusion360を用いた３DCADからCNC加工の手法

#３DCAD→CAM→CNC加工において
Fusion360で3D設計しdxf化、CAMを今まで使用している環境で行おうとしている人向けの情報となります。

Fusion360でCAMまででき、高性能であるが、CAMは使えるようになるまで細かい設定やら、ポストプロセッサの改善修正（Z軸を移動させる前にXYの移動が入っている。切削終了後にXYの原点に戻る。）と他のCAMと同じレベルに使えられるようになるまでに手間がかかる。
fusion側でも改善が入り、ポストプロセッサの問題点も解決できるように項目欄が増えてきているが、初めて使うには難易度が高いと感じたため、前の環境を部分的に使えるようにすることにした。

#fusion360の凄い点
無料
無料の為、情報が多い
アセンブリができる
３次元加工のCAM、シミュレーションまでできる。
歯車の設計もスクリプトで簡単に出来る。

#fusion360→CNCの流れにして変わった点
メリット：
３Dプリンターを使用するようになり、情報の多いfusion360の環境を導入したため、CNC加工もfusion360に統一できた。
Fusion360で共通設計にしたため３Dプリンターで試作、CNCで本番の部品が作る流れがスムーズになった。

デメリット：
DXF化はスケッチ１面のみなので、押し出しした上に書いたスケッチは、一つのスケッチにまとめないとDXF化できない。
バグ？があり、DXF化の注意点がある。

以前の方法；
→3D設計　Autodesk　Inventor:ファイル形式dxf化
→データの並びの整理　Autodesk AutoCAD:dxf複数のデータをmm単位で並べなおす
→CAM　DesKAM2000：gコード化

新しいの方法：
→3D設計　fusion360:複数データをミリ単位で並びなおし、dxf化
→CAM　DesKAM2000：gコード化

#手順
タブのスケッチにて右クリックで「DXF形式で保存」で保存することで、DXFで出力される。

#注意点
下書き線としてコンストラクションを使用した際（オレンジの点線）、
CAMでみると線として認識してしまうので消す。
原点に合わせると、線が消えてしまうことがあるため、少しずらす必要がある。


 ![a1.JPG](https://qiita-image-store.s3.amazonaws.com/0/247563/749bac50-d852-3969-8a8d-448e97f59c55.jpeg)

図　Fusion360　コンストラクションを残した状態のスケッチ
 ![a2.JPG](https://qiita-image-store.s3.amazonaws.com/0/247563/0b7583fd-ff4f-f24b-6fa8-090f847adf2f.jpeg)

図　DesKAMで開いたdxf、コンストラクションが線として認識されている。

 ![a5.JPG](https://qiita-image-store.s3.amazonaws.com/0/247563/535ed112-cf9a-083f-6c83-a7f1ea95d4c0.jpeg)

図　Fusion360：原点に線がある状態でDesCAMで読んで線がない状態になったdxf

#未解決問題
半円を用いた図をdxfにした際、半円部分が読み込まれず、直線になるor円として認識されてしまう。
この問題はautodeskの出力形式による影響で、autodesk同士のソフトだとしっかり読み込まれる。
対応として、CAM側でラインの再指定をする方法しか見つからなかった。autocadでpeditで線同士の結合、再度dxfで出力もしたが効果はなかった。
新しいCAMソフトであると認識される可能性がある。

![2.JPG](https://qiita-image-store.s3.amazonaws.com/0/247563/39a48c9c-24d0-1be5-962c-3553bceec458.jpeg)
図　CAM側で上下で同じ図にて半円が認識されていない様子

![4.JPG](https://qiita-image-store.s3.amazonaws.com/0/247563/68c54760-7ce3-c3d8-15be-4699a382c144.jpeg)
図　CAM側でラインの再指定をできるように、半円を認識させるため、半円部分を直線でつないで埋めると認識する。

#DXFの追加
fusion360への上の欄にて、挿入でdxfを読み込める。


#情報の集め方	
基本的な操作は、youtubeに多数上がっており、学べられる。	
勉強会が各地で行われており、AUTODESK FUSION360公式の講習会もあり、fusion360からレーザープリンタ、CNC、３Dプリンターまでの一連の操作を学べる。
個人サイトで、fusion360のCAMを使い、CNC加工している人のページも2018年６月頃では１０数個見つかる。ここ1,2年でできるようになったため、今後サイトは増えていく。
またFusion360は更新頻度が多く、使いやすくなっているが海外の情報が速いことがあり、最新の情報は外国の掲示板探すと見つかることがある。
HTMLのidとclass

#初心者がHTMLとCSSを勉強してややこしかったこと
　HTMLとCSSを勉強して1週間が経ちました。Progateの[「HTML & CSS 初級編」](https://prog-8.com/languages/html)とドットインストールの[「【旧版】HTML基礎文法入門」](https://dotinstall.com/lessons/basic_html_v3)で勉強してきました。最初はHTMLとCSSのつながりが分かりづらかったものの、段々とつかめてきたような気がします。その中で、"id"と"class"の違いが分かりづらかったのでここでシェアします。

##idとclass
idとclassはいわゆるタグ付けになります。HTMLでタグ付けをし、CSSでタグ付けした部分を修飾するというときに使います。例えばですが、

### id
HTML

```html

<h1 id="title">What's up guys?<h1>
```
CSS

```css
#title{color:blue;}
```

### class
HTML

```html
<h1 class="title">What's up guys?<h1>
```

CSS

```css
.title{color:blue;}
```

といった形で記入すると、What's up guys?というタイトルが青色になるわけです。id/classどちらを用いても表示は同じです。
では"id""class"の違いは何なのでしょうか。

## idとclassの違い
　idは１ページ中１度しか使えない。classは何どでも使える。
これが違いです。一見全部classでいいように思われますが、優先度はid>classなので、一つここだけ特定したい場合にidは有効です。
　classはどんどん上書きされていくので、上書きされたくない内容はidを用いればよいでしょう。また、コードを見た際にidで記しておいたところは特定しやすいです。


**参考記事**
[スタイルシートの class と id の違いと使い分け](https://allabout.co.jp/gm/gc/23897/)
PyQuery でWebページのリンクを抽出する

こちらのページで、Beautifulsoup4 で行っていることを PyQuery で行って見ました。

```py:get_links.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#	get_links.py
#
#					Jul/18/2018
#
# ------------------------------------------------------------------
import sys
from pyquery import PyQuery

sys.stderr.write("*** start ***\n")

url = sys.argv[1]

try:
	qq = PyQuery(url=url)

	for elem in qq.find('a'):
		q2 = PyQuery(elem)
		print(q2.attr('href'))
except Exception as ee:
    sys.stderr.write("*** error *** in PyQuery ***\n")
    sys.stderr.write(str(ee) + "\n")
#
sys.stderr.write("*** end ***\n")
# ------------------------------------------------------------------
```

使い方のサンプル

```bash
./get_links.py  https://ekzemplaro.org
```
wemosでアセンブラ

#概要
wemos　d1でアセンブラやってみた。

#サンプルコード


```
extern "C" {
	#include "ets_sys.h"
	#include "osapi.h"
	#include "gpio.h"
	#include "user_interface.h"
}
byte YELLOW_pin = 4;
byte BLUE_pin = 12;
void toggle_blue_yellow__asm()
// yellow pin = 4  => bit mask = 16d, [0...0]10000 (32 bit)
// blue pin   = 12 => bit mask = 4096d, [0...0]1 0000 0000 0000 (32 bit)
// PIN_OUT_SET   : 0x60000304
// PIN_OUT_CLEAR : 0x60000308
//
{
	asm volatile (
	"movi    a2, 0x60000304;" // SET Address in a2
	"movi    a3, 0x60000308;" // CLEAR Address in a3
	"movi    a4, 16;"         // yellow pin bit mask in a4
	"movi    a5, 4096;"       // blue pin bit mask in a5
	"movi    a6, 12;"         // delay loop counter
	"s32i    a4, a3, 0;"      // set yellow to LOW
	"memw;"
	"s32i    a5, a2, 0;"      // set blue to HIGH
	"memw;"
	"label1:"
	"addi    a6, a6, -1;"
	"NOP;"
	"NOP;"
	"NOP;"
	"NOP;"
	"bnez    a6, label1;"
	"movi    a6, 12;"         // delay loop counter
	"s32i    a4, a2, 0;"      // set yellow to HIGH
	"memw;"
	"s32i    a5, a3, 0;"      // set blue to LOW
	"memw;"
	"label2:"
	"addi    a6, a6, -1;"
	"NOP;"
	"NOP;"
	"NOP;"
	"NOP;"
	"bnez    a6, label2;"
	"movi    a6, 12;"         // delay loop counter
	"s32i    a4, a3, 0;"      // set yellow to LOW
	"memw;"
	"s32i    a5, a3, 0;"      // set blue to LOW
	"memw;"
	"label3:"
	"addi    a6, a6, -1;"
	"NOP;"
	"NOP;"
	"NOP;"
	"NOP;"
	"bnez    a6, label3;"
	"movi    a6, 12;"         // delay loop counter
	"s32i    a4, a2, 0;"      // set yellow to HIGH
	"memw;"
	"s32i    a5, a2, 0;"      // set blue to HIGH
	"memw;"
	"label4:"
	"addi    a6, a6, -1;"
	"NOP;"
	"NOP;"
	"NOP;"
	"NOP;"
	"bnez    a6, label4;"
	::
	: "a2", "a3", "a4", "a5", "a6", "memory"
	);
}
void setup()
{
	pinMode(YELLOW_pin, OUTPUT_OPEN_DRAIN);
	pinMode(BLUE_pin, OUTPUT_OPEN_DRAIN);
}
void loop()
{
	delay(10);
	toggle_blue_yellow__asm();
}




```

以上。
AWS Cloud9を東京リージョンのEC2で使う方法

#はじめに
AWS Cloud9はブラウザで操作ができるクラウドベースのIDEです。
2018年7月現在、AWS Cloud9でサポートしているリージョンは
シンガポール、バージニア北部、オハイオ、アイルランド、オレゴンの5つで、
東京リージョンがサポートされていません。
しかし、東京リージョンのEC2でAWS Cloud9を使いたい方も多いと思うので、その方法を説明していきます。

*(追記)2019/4/9に東京リージョンも正式にサポートされたようです。

#①EC2インスタンスの作成
まずは、Cloud9を利用したい東京リージョンのEC2インスタンスを作成します。
※既にEC2インスタンスがある方はスキップしてください。
AWSマネジメントコンソールのEC2ダッシュボードでリージョンが東京になっていることを確認してインスタンスの作成を押します。
![図1.png](https://qiita-image-store.s3.amazonaws.com/0/270692/6ddf2f7a-35a6-bb85-b1a2-e5e40b8e9677.png)

今回、AMIは「Amazon Linux 2 AMI (HVM), SSD Volume Type」、
インスタンスタイプはt2.micro、他はデフォルトで作成しました。
※Ubuntuとかp2インスタンスとかでもcloud9は使えます。

#②Elastic IPの割り当て
次にEIP(Elastic IP)をEC2インスタンスに割り当てます。
EIPを割り当てないと再起動する度にIPが変わって、Cloud9の設定を変える必要があるので不便です。
Elastic IPのタブで新しいアドレスの割り当てからEIPを取得し、アドレスの関連付けで先ほど作成したEC2インスタンスを選択してください。
![図2.png](https://qiita-image-store.s3.amazonaws.com/0/270692/d22d8950-aec1-7921-7481-efc2b4c8dbef.png)

#③node.jsのインストール
TeraTerm等で先ほど作成したEC2インスタンスにログインします。
ログインしたら以下のコマンドでnode.jsがあるか確認します。node.jsがインストールされていないとCloud9が使用できません。


```
$ node --version
```

node.jsがインストールされていなければ、AmazonLinuxの場合は以下のコマンドでインストールします。

```
$ curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash -
$ sudo yum -y install nodejs
$ node --version
```
node.jsが無事にインストールされたことを確認します。

#④AWS Cloud9の環境構築
画面上のサービスからCloud9を検索してクリックします。
以下の画面が出てくるので、アジアパシフィック(シンガポール)を選択します。
![図3.png](https://qiita-image-store.s3.amazonaws.com/0/270692/ce88a547-5a3a-ac05-2a67-1c2a500ba38d.png)

AWS Cloud9の画面が出てくるので、「Create environment」をクリックします。
Step1のName environmentで名前を入力します。Descriptionは空欄で大丈夫です。
![図4.png](https://qiita-image-store.s3.amazonaws.com/0/270692/f8b7bdc0-23be-7fd9-5a09-d5761dd82682.png)

Step2のConfigure settingsで「Connect and run in remote server (SSH)」を選択します。
UserにはAmazonLinuxならec2-user,HostにはEIPを入力します。
![図9.png](https://qiita-image-store.s3.amazonaws.com/0/270692/252bd86e-48b7-2c41-066e-3a6a1c413f9d.png)

次に「Copy key to clipboard」をクリックしてpublic SSH keyをコピーします。
EC2インスタンスで以下のコマンドを実行し、authorized_keysファイルを開きます。

```
$ vim ~/.ssh/authorized_keys 
```
既にSSH keyが1つ登録されているので、一行下に先ほどのSSH keyを貼り付けます。
AWS Cloud9の画面に戻ってNext stepをクリックします。

Step3のReviewで内容を確認してCreate environmentをクリックします。
インストールの画面が出てくるので、Nextを押してインストールします。
![図6.png](https://qiita-image-store.s3.amazonaws.com/0/270692/9cd4bf8a-caab-8887-2b1d-79afc89a78d0.png)
インストール途中でY/nと聞かれたらYを入力してEnterを押します。
しばらくして画面に「Installation Completed.」と表示されるとインストール完了です。

#⑤AWS Cloud9にアクセス
アジアパシフィック(シンガポール)のAWS Cloud9に行くと、先ほど作成した環境が表示されるので「Open IDE」をクリックします。
![図7.png](https://qiita-image-store.s3.amazonaws.com/0/270692/a40fed38-8f9f-ce67-f438-5783384591a5.png)

AWS Cloud9が起動しました。
![図8.png](https://qiita-image-store.s3.amazonaws.com/0/270692/5ade8263-1c1a-ed10-a92d-ff3bb4e4d679.png)
 
以上で、AWS Cloud9を東京リージョンのEC2インスタンスで使うことができるようになりました。
Seleniumで自動テスト

SeleniumでWebブラウザを使った自動テストが作成できます。
プログラムで作成する方法とノンプログラムでやる方法があります。

# ノンプログラム方式

Selenium IDEというブラウザの操作をスクリプトに自動記憶させ、それを再生する事で自動テストを行います。
このやり方だと自由度が低く、効率的な運用には即さないです。
プログラムが書けない場合には有効だとは思います。

# プログラム方式

SeleniumからWebDriverというライブラリが提供されています。下記の4言語が公式です。
- Java
- Javascript
- C#
- Python

この公式ライブラリとテストフレームワークを組み合わせて、自動テストを作成します。
自由度も高く、効率的な運用ができます。

WebDriverに「Javascript」、テストフレームワークに「mocha」を使ったサンプルを書いておきます。


### 環境構築
nvm と nodeをインストールします。

### 必要なライブラリインストール
javascriptのWebDriverをインストールします。
テストフレームワークとして使うmochaとexpectを使います。
mochaにはアサーション機能がないので、expectも使います。

```
npm -g install selenium-webdriver
npm install mocha
npm install expect.js
```

### package.json作成

```
npm init
```

### ChromeDriverをインストール

Chromeを使ったサンプルなので、ChromeDriverをインストールします。
[ChromeDriver](http://chromedriver.chromium.org/downloads)

### サンプルソース実装

``` javascript
var webdriver = require('selenium-webdriver');
var expect = require('expect.js');
var assert = require('assert');
var By = webdriver.By;

describe('test sample', function(){
    this.timeout(15000);

    let browser;

    // テスト開始前に行う処理
    before(() => {
        browser = new webdriver.Builder().forBrowser('chrome').build();
    });

    // テスト終了時に行う処理
    after(() => {
        browser.quit();
    });

    // テスト内容(itを複数記述できる)
    it('web app test1 success', async function() {
        // googleホームページを起動する。
        await browser.get('https://google.co.jp');

        //テスト処理
        let targetValue = await browser.getTitle();
        expect(targetValue).to.be('Google');
    });

    it('web app test2 error', async function() {
        // googleホームページを起動する。
        await browser.get('https://google.co.jp');

        //テスト処理
        let targetValue = await browser.getTitle();
        expect(targetValue).to.be('Google111');
    });
});
```

### サンプル実行

```
npm test sample.js
```

これでブラウザが起動し、タイトルが「Google」かチェックし、その結果が標準出力されます。
ElasticsearchのDynamicTemplateのメモ

Elasticsearchを使う機会があって、
DynamicTemplateを使用したので、そのときのメモです。
メモなので雑です。

DynamicTemplateは、elasticsearchにデータをアップロードする際、
elasticsearchが自動でフィールドの型設定をしてくれるのですが、
特定の文字列にマッチする場合に、適用する設定のことです。

つまり
「このindexに、この名前でデータがアップロードされたら、こうしてね」
ということですね。

「`path_to_apply_*`の中にある、「`text_*`」に該当するものは日本語解析可能にする」
という設定のjson

```json:mapping_template.json
{
  "template": "path_to_apply*",
  "settings": {
    "index": {
      "analysis": {
        "tokenizer": {
          "kuromoji_user_dict": {
            "type": "kuromoji_tokenizer",
            "mode": "serach"
          }
        }
      }
    }
  },
  "mappings": {
    "_default_": {
      "dynamic_templates": [
        {
          "named_analyzers": {
            "match_mapping_type": "string",
            "match": "text_*",
            "mapping": {
              "fielddata": true,
              "analyzer": "kuromoji",
              "fields": {
                "keyword": {
                  "type": "keyword"
                }
              }
            }
          }
        }
      ]
    }
  }
}
```

以下のコマンドで適用します。

```bash
$ curl -X PUT 'endpoint:port/_template/path_to_apply' -d @mapping_template.json
```
最小構成実行環境の整備【heroku sinatra mecab】

# やりたいこと

Qiitadon みてたら、「MeCabを用いたSinatraアプリケーションをHerokuにデプロイしようとしてつまづいております。どなたかお助けを…」って言っている人がいたので、助けに行く。

トゥート：https://qiitadon.com/@a_ta/100382612720547690  
(Qiitadonの埋め込みができないよ、Qiitaさん！)

## 目標

- heroku 上で sinatra を使って公開しているアプリで mecab を使いたい
- 最低限のコードで動くものを目指す

## 環境

- heroku 無料枠
- ruby 2.3.7
- mecab 0.996

## ファイル

```:ファイル構造
mecab_on_heroku
  ├── .gitignore
  ├── Gemfile
  ├── Gemfile.lock
  ├── Procfile
  └── app.rb
```

### ファイル内容

```:.gitignore
/vendor
```

```ruby:Gemfile
ruby "2.3.7"
source 'https://rubygems.org'
gem 'sinatra'
gem 'mecab', '0.996'
```

```ruby:Procfile
web: ruby app.rb
```

```ruby:app.rb
require 'sinatra'
require 'mecab'

get '/' do
  str = "我々宇宙人は地球を侵略しに来ました。"
  tagger = MeCab::Tagger.new
  "#{tagger.parse(str)}"
end
```

Gemfile.lock は Gemfile を保存してから以下のコマンドを実行すると作成される。

```sh:コマンド実行
bundle install --path vendor/bundle
```

## heroku のデプロイ

```sh
cd mecab_on_heroku  # 任意の作業ディレクトリ
heroku create -a heroku_app_name --buildpack https://github.com/diasks2/heroku-buildpack-mecab.git
heroku config:set LD_LIBRARY_PATH=/app/vendor/mecab/lib
```

[ファイル構造](#ファイル)で示した5つのファイルを作成したのち、下記のコマンドを実行する。

```
git add .
git commit -m "first commit."
git push heroku master
```

## 動作確認

以下のコマンドを実行すると、自動でデフォルトブラウザが開き、heroku アプリにアクセスする。

```sh
heroku open
```

## 参照ページ

[GitHub: heroku-buildpack-mecab リポジトリページ](https://github.com/diasks2/heroku-buildpack-mecab)
virtual-box(CentOS7)とRuby,Railsの始め方(参考サイト)まとめ


<h2> virtual-boxの導入とrailsの起動までを参考サイトをまとめただけ:wink:</h2>
<p><strong>背景:</strong></p>

windowsマシンに仮想環境(vm)を導入したことがあります。
今回はmacに導入してみました。
インストールするOSは使ったことのないosが良いと思い、kali-linux(debian系)を一度入れたのですがやはり実用性考えて再度centOS7をインストールしました。

<p><strong>やったこと:</strong></p>

<strong>何回も調べるのは非効率なのでメモ程度にまとめました。</strong>

<h2>virtual-boxの導入手順 </h2>
https://qiita.com/100/items/80a899fbaeb1e82b3f67

コピペできるのでその手順もみておきましょう。
※端末でctr+cなどでコピーしたら、vmのcentOS側ではctr+shift+vでペーストできるはずです。

<h2>解像度がおかしいのでこちら</h2>
https://usado.jp/spdsk/2017/10/24/post-2333/

<h2>githubを入れる</h2>
https://qiita.com/copei/items/710a2d05114ec1637268

<h2>Ruby+Railsを導入する。</h2>
まとまっていてわかりやすいです。
https://qiita.com/iamdaisuke/items/46da26b4060ddec18895

※バージョンがあるかは確認したほうがいいですね
$ rbenv install -l | grep 2.3.1
  2.3.1

※実際にrubyをインストールするときは5分くらいかかるかも？

試しに自分が動かしたいアプリをgitからcloneしてみる。
<code>$ git clone hoge.git</code>
<code>$ bundle install</code>
私はエラーが出たのでその通りにmysql(db)を入れます。
<code>$ sudo yum install mysql-devel</code>
<code>$ rails s</code>
なんとか起動まで持ってげました。:confused:


<h2>感想とか</h2>
ブラウザは重たい印象。それ以外は以外とスイスイでした。
過去にpcにvm建てたときはvmの動作そのものが重たい印象だったので、macにvmありだなと。ただ個人的には使うコマンドはさほど差分ないのでmacオンリーでも覚えられると思いますが、別環境でも自分が作ったアプリ動くのか試したい場合にはいいのかも？
7-Zipを使用してファイルを分割する

メールで容量の大きいファイルを送ることがしばしばあります（クラウドサービス？なにそれ(・・?）
しかし、企業のメールクライアントって容量制限が厳しかったりします❗5MBとか❗
そこで7-Zipを使ってサイズが大きいファイルを分割したいと思います😆


##分割方法

（7-Zipが標準インストールされている前提ですすめます）
以下コマンドを叩きます

```
C:¥Program Files¥7-Zip¥7z.exe a -v2m [圧縮後のファイル] [圧縮前のファイル]
```

「-v」の後ろの「2m」が分割後のファイルサイズを表しています（この場合は2MB)
㌔ならk、㌐ならgを使えば良いです

##結合方法
batファイルを作成しておくといろいろ捗ります（メール送付先の人はどうせコマンドプロンプトなんか使えません😌）
以下のように記述します

```
COPY /B [圧縮後のファイル].001+[圧縮後のファイル].002 結合ファイル名
pause
```

ファイルの数だけ「+」で連結していきます
batにする場合、最後にpauseを入れておくとコマンドプロンプトが勝手に閉じないためエラーメッセージ等が確認できて良いですよ❗
Macで絵文字を打つ方法

TwitterやSlackでよく見る絵文字😀ですが，
てっきりiOSやAndroidのスマホからしか入力できないと思っていましたが
<kbd><kbd>Ctrl</kbd>+<kbd>⌘</kbd>+<kbd>Space</kbd></kbd>で入力できるみたいです
ハッピー絵文字ライフ😄😄😄😄😄
【GitKraken】Git LFSのfetchやpullが出来ないとき

# 起きた問題

Git LFSを利用し始めたときにfetchやpullが出来ない現象に見舞われました。
改めてcloneしてみたり、転送量やストレージに問題があるのかとdata packを購入しましたが解決に至りませんでした。

![2018-07-18_01h56_16.png](https://qiita-image-store.s3.amazonaws.com/0/126970/11adc1a9-546a-4481-5f43-b8b039526358.png)

![2018-07-18_01h42_33.png](https://qiita-image-store.s3.amazonaws.com/0/126970/ea788491-c699-6a64-4093-34c2ea6e82b9.png)

# 解決方法

暫定的な解決方法ですが
`Preferences > Authentication > GitHub.com > SSH Key`から
SSH Keyを削除することで解決しました。
SSH Keyを削除することによる不都合もあるため原因をご存じの方がいらっしゃいましたらご教示いただけますと幸いです。

![2018-07-18_02h06_23.png](https://qiita-image-store.s3.amazonaws.com/0/126970/aafa13c7-40d4-f979-53c6-4c1c7098ac50.png)

![2018-07-18_02h17_22.png](https://qiita-image-store.s3.amazonaws.com/0/126970/4efa60c9-b47d-ca0c-8db9-e3fb1e3c58d6.png)
エクスプローラで開いているフォルダをVSCodeで開く右クリックメニューを作る

# 追記
VSCodeの右クリックメニューはインストール時に指定すれば設定できるそうです.
この記事の内容は右クリックメニューの作り方って感じで見てください(

# 前書き
ある時ディレクトリ内で右クリックのメニューを開いてみると，下の画像のようになっていました．
赤枠で囲んだ部分は明らかに標準では付いていないものです

![image.png](https://qiita-image-store.s3.amazonaws.com/0/170422/0bf95cfa-f4fb-b80d-e5b2-8d9397f9950a.png)

~~正直Visual Studioはあまり使わないので~~ VSCodeでフォルダを開く機能があれば便利だなーと思っていました

これを，下の画像のように自作のメニューを追加します
![image.png](https://qiita-image-store.s3.amazonaws.com/0/170422/9e3cb7ac-92b4-15c5-0a15-1c0309fe7b61.png)

# 作り方
この手のメニューの追加は，レジストリエディターを使用します
**※レジストリを書き換えるので自己責任でお願いします**

1. レジストリエディタを起動します
  * [Win+R]のファイル名を指定して実行から，```regedit```と入力します
  
  ![image.png](https://qiita-image-store.s3.amazonaws.com/0/170422/008f0b19-be36-638f-0007-f7b99a18ad3a.png)
1. キーを追加する場所を探します
  * 既に存在していた[Hyper](https://hyper.is/)の起動メニューの文面から検索して，以下の場所にあることを確認しました．
    * ```コンピューター\HKEY_CLASSES_ROOT\Directory\Background\shell``` 
    
![image.png](https://qiita-image-store.s3.amazonaws.com/0/170422/f7ebbe23-34ca-4627-5cc0-d43155c89504.png)
1. キーを追加する
  * Shellを選択し，[右クリック]→[新規]→[キー]の順に選択します．
  ![image.png](https://qiita-image-store.s3.amazonaws.com/0/170422/66f0ed89-021d-4263-2226-eeb581cf8b29.png)
  * キーの名前を要求されるので，適当に```VSCode```とでも書いておきましょう．
  * 次に，右のウィンドウから，[既定]の部分をダブルクリックします．
  * 文字列の入力を求められ，ここで入力した値が右クリックをした時に表示されるメッセージになります．
        * 今回は```VSCodeで開く(&C)```としてみました．
        * ```&```を付けるとショートカットキーを設定できます．
        ![image.png](https://qiita-image-store.s3.amazonaws.com/0/170422/5989092b-dd31-b14e-c09d-762bdf25d002.png)

1. 実行するプログラムを設定する
  * 次に，作成したメニューをクリックした時に起こすアクションを設定します
  * 先に作成した```コンピューター \HKEY_CLASSES_ROOT\Directory\Background\shell\VSCode```で右クリックし，もう一つ新しいキーを作成します．
  * キーの名前は，他のキーを参考にして```command```にします．
  * キーのデータは，以下のようにします(VSCodeの実行パスは適宜変更してください)
  
  ![image.png](https://qiita-image-store.s3.amazonaws.com/0/170422/050450ff-407c-8fa5-8fb0-a4ac93a938a2.png)
  * 最終的に以下のような画面になりました．
  
  ![image.png](https://qiita-image-store.s3.amazonaws.com/0/170422/a3fcb373-2ec3-1343-c78e-f7fbdff731e3.png)

# 結果
(初めに映したものと同じです)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/170422/9e3cb7ac-92b4-15c5-0a15-1c0309fe7b61.png)

これで，フォルダ上で右クリックを押すとそのフォルダをVSCodeで開くメニューが完成しました．
使用する機会によっては，VSCodeを開いてから，フォルダをドロップするよりも安定した操作ができ，場合によってはVSCode側のフォルダを開くコマンド```[C-K→F]```よりも使いやすい場面も有るでしょう．
vimを導入しよう

久しぶりの投稿です。
開発で主にRubyやPythonとかスクリプト系の言語が多かったため、最初はSublimeText3を
使っていましたが、ここ最近は業務的にターミナルから出ることがあまり無くて切り替えるのが
面倒くさかったため、思い切ってvimを使ってみようと思いました。整理がてらまとめてみます。
今回は環境構築という点から導入編です。

### 現在の環境
最初はvimだけ使っていたのですが、いろんなものを試して現在は以下のようになりました。

- パッケージマネージャ：Homebrew
- ターミナル：iterm2
- シェル：zsh
- エディタ：neovim
- vimプラグインマネージャ：vim-plug (deinが多いようですが、自分はこっちです)
- その他使ってるもの（結構使うものだけ）
    - tmux（仮想端末マネージャ）
    - fzf（CLIのFuzzyFinder、vimやtmuxと相性が良い）

tmuxを使っているのは「画面分割して、同期操作をしたかったから」です。
iterm2でも、command+Dとかcommand+shift+Dとか押すと分割できて、command+shift+Iと押すと
表示されている画面に同じコマンドを叩くことができるようになります。
なんですが、タブを複数開いて操作するとコマンドが別のタブにまで送信されてしまうようで、、、（今は治ってる？）
そのおかげでステージング環境で打ったコマンドが本番に…みたいな事故が発生。。。
代替としてtmuxを使うようになりました。

### インストール
vimはHomebrewから入れたほうが楽です。なのでbrewをまず導入
ホームページに書かれていますが、以下コマンド。

```bash
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

あとは勝手に入ります。```brew```などコマンドを打って通ればOKです。
brew自体の使い方は良い記事が結構あるのでそちらを参考にして下さい。

#### 1.neovim  
これがないと始まらないですよね。以下コマンド

```bash
# HEADオプションはなくても良いです
brew install --HEAD neovim
```

#### 2.iterm2
[ダウンロードページ](https://www.iterm2.com/downloads.html)から落としてきてインストールして下さい。
カラースキームはTomorrow-Nightベースでカスタマイズしたもの、Themeは[pure](https://github.com/sindresorhus/pure)というシンプルな
デザインなものを使用しています。

#### 3.tmux
これもHomebrewで

```bash
brew install tmux
```

```tmux``` と打てば起動します。vimと同じように設定ファイル（tmux.conf）がありキーバインドや
tmux用プラグインの導入も行えます。

#### 4.fzf
Homebrewから入れてもいいですしvimプラグインからインストールしてもいいですが、
brewが楽なので。

```bash
brew install fzf
```

brewで入れた場合は、ランタイムをvimrcに追記する必要があります

```vim
# インストール先を指定
set rtp+=/usr/local/opt/fzf
```

fzf自体の使い方や設定はGitHubのwikiに細かく載っていますので、かなり参考になると思います。
オプションが充実していて、ちょっとしたスクリプトやfunctionを書けばいろんなことができます。
（fzfよりpecoの方が使っている人が多いのか…）

3と4は使いたい人だけ入れて下さい。自分はないとちょっとつらいですね。。

### まとめ
長くなりそうだったので、概要とインストールだけ記述しました。
今後は、vimプラグインやvimのキーバインド設定、fzfの使い方とかまとめてみようかと思います。
取引ナビから宛名を取得。(ラベルシール印刷ソフト用)(ヤフオク個人出品者向け ブックマークレット)

## はじめに。

取引ナビでは 上から「名前→郵便番号→住所」となっており宛名シールに印刷するためのものとしては順番がおかしく、若干の編集が必要なため、わずかに その手間を減らすために作ったものです。
住所に建物名が くっついていたり、住所そのものが やたら長かったりする場合もあるので、結局 編集は必要です。
このブックマークレットでコピーし、それを宛名シール印刷ソフトにペーストする。という使い方をしています。
ちなみに、俺が使ってるのは A-one の [ラベル屋さん9](http://www.labelyasan.com/support/download/)です。

## 動作確認環境

Windows 10
Google Chrome 67

## 使い方。

※ 取引ナビで「発送連絡をする」ボタンが表示されている画面で使用することを想定しています。特定の行を決め打ちで取得してきているため、別の画面では正常に取得できません。(2018-09-22 追記)

取引ナビで このブックマークレットを起動。
コピーされた内容が、Toastもどきで表示されるので、一応 目視で確認。
それを、宛名シール印刷ソフトへペースト。
そして、若干の編集。

※ 定形外で使うことを想定しており、ゆうパケット(おてがる版)などでは正常に動作しないことを確認しています。

## コード。

特に難しいことはしていませんし、細かい説明はコードのコメントを読んでもらえれば分かるかと思います。

```javascript

javascript:(function(){

/* 取引ナビから 名前 郵便番号 住所 を取得（メインは この三行だけ） */

var arrs=document.getElementsByClassName("decCnfWr");
var p= arrs[2].innerHTML;
var o=p.substr(0,4)+"-"+p.substr(4,4)+"\n\n"+arrs[3].innerHTML+"\n\n"+arrs[1].innerHTML+" 様";

/* 順序を 郵便番号 住所 名前 に(ついでに「様」も追加)したものを、クリップボードへコピー。 */ 

var ta = document.createElement("textarea");
document.body.appendChild(ta);
ta.value=o.toString();

ta.select();

if (document.execCommand("copy")) { 

/* Toastもどき(正直、なくてもいい) */

var sc = document.scrollingElement.scrollTop; 

var text = document.createElement("span");
text.innerHTML="クリップボードへコピーしました。<br><br>" + o.replace(/\n/g, '<br>');

var ts = text.style;

ts.color = '#000';
ts.backgroundColor = 'white';
ts.padding = '15px';
ts.border = '1px solid gainsboro';
ts.boxShadow = '3px 3px 10px';
ts.zIndex = '100';

document.body.appendChild(text);

ts.position = 'absolute'; 
ts.top = 50 + sc + 'px'; 
ts.left = (window.innerWidth / 2)-(text.offsetWidth / 2) + 'px'; 

setTimeout(function () { text.style.visibility = "hidden"; }, 1500);

}

document.body.removeChild(ta);

})()
```

## おわりに。

一応、自分でも使ってますが、ちょいちょい手直しを加えていったものなので、どこか おかしいかもしれません。
なんか おかしな所を発見しましたら、ご一報ください。
こちらでも同じ現象が確認できた場合、修正します。(2018-09-22 追記)
Android Architecture Components の ViewModel って…一体何者だ？

# 概要

今まで onSaveInstanceState をシコシコ書いて頑張っていた人向けの Android Architecture Components の ViewModel 解説記事です。

ちなみに ViewModel の公式の記事は以下になります。

* [ViewModel Overview](https://developer.android.com/topic/libraries/architecture/viewmodel)
  * （参考）[【Android Architecture Components】ViewModel 和訳](https://qiita.com/oya-t/items/9aa80042e6fc10d32d49)

より詳しく知っている人からの突っ込み歓迎です。

# 背景

なんでこの記事を書こうと思ったかというと、自分が理解に超絶苦しんだからです；；

Android Architecture Components の ViewModel は、画面回転時などの Activity 再構築に対処するための技術です。

同様の対応方法の一つに Activity#onSaveInstanceState があります（もうひとつ方法があるじゃん！と突っ込みを入れたくてうずうずしている方はこの記事の想定読者ではありませんゾ！）。

Activity#onSaveInstanceState による対処法は制約が多く実装もちょっと複雑です。
例えば扱える情報には Percerable や Serializable といった制約があります。これは一時的なディスクへの保存に由来する制約です。また、復元されたオブジェクトは再構築前のオブジェクトとは別インスタンスになるという点も注意が必要です。

一方で ViewModel クラスによる方法は制約も少なく実装も簡単です。

私は Activity#onSaveInstanceState には色々と制約があったためかなり身構えました。また、いったいどうやって実現されているのかまったく想像ができず、やっていいこと・わるいことの判断がつきませんでした。

そのあたりを踏まえた解説をしたいと思います。

# ViewModel はディスク保存ではない！

まず最初に ViewModel はディスク保存ではありません。単純に ViewModel は Activity の再構築時にも壊されることなくメモリ上に残り続けることができるオブジェクトだと思っていいと思います。そのため Percerable や Serializable 等の制約は一切ありません。Activity 再構築前と再構築後で変わることのない全く同一のインスタンスです。当然ながらインスタンスが持つ各種参照は維持されます。

このことは公式ページの「The lifecycle of a ViewModel」の説明のところに記載がありますが、Activity#onSaveInstanceState の先入観に捕らわれた状態では理解できませんでした。

ViewModel は Activity の再構築を越えることのできる長寿オブジェクトなのです！

# どうやって Activity の再構築を越えることができるのか？

そんなのどうやってるの？という疑問が湧きますよね。湧きませんか？実はその方法はかなり昔からあるようなのです。Android 3.0 の時代（API level 11）からです。

その方法とは Fragment#setRetainInstance メソッドを使う方法です。公式のドキュメントでも onSaveInstanceState と並んで紹介されています。

* [実行時の変更の処理 - 構成の変更中にオブジェクトを保持する](https://developer.android.com/guide/topics/resources/runtime-changes#RetainingAnObject)

私はこの方法を知りませんでした。

ViewModel の実装を読み進めていくと、この Fragment#setRetainInstance メソッドを使った Fragment が出てきます。Fragment#setRetainInstance メソッドが何か怪しいと思って調べたところ、これが onSaveInstanceState に並ぶ別の方法であることが分かりました。

ちなみに Fragment#setRetainInstance は、Fragment を Activity の再構築時に破壊されないようにするための技術なので、汎用的にオブジェクトを格納するためには周辺の実装を色々と自分で作らないといけません。面倒ですね。

そこで ViewModel です。要は ViewModel は Fragment#setRetainInstance を使った方法を、簡単にそして便利に使えるようにしたラッパーなんですね！

# メモリ上に存続し続けるオブジェクトなので！

これまでの説明で ViewModel の正体がわかったでしょうか？
onSaveInstanceState の方法とは違い Fragment#setRetainInstance を使ったメモリにオブジェクトを存続し続けるための技術です。

ということは…。

* onSaveInstanceState とは違って別に ViewModel は Percerable や Serializable である必要はありません。

自由に作れます。参照も維持されます。

ですが、何でも自由なわけではないです。作る際に以下の制約があります。当然、公式のドキュメントにも書いてあります。

* ViewModel よりも寿命が短いオブジェクトの参照を持ち続けてはなりません。

ViewModel は再構築される Activitiy よりも寿命が長いです。もしも Activity の参照を ViewModel が持ってしまったら、寿命が切れた Activity の参照を持ち続けてしまいます。それは（実際には確かめてはいないが）Activity がガーベジコレクションの対象から外れることを意味します。メモリ上に残ったままになってしまうということです。

なので Activitiy や Fragment や View 等を参照してはならないわけです。

また、ディスクに退避されることがなく、別のアプリにフォーカスが移動した際もメモリ上に展開されたままになると想像できるので、大量のメモリを消費するのも問題かもしれませんね。

以上です！
RealSense python メモ

# pythonから色々したい時のメモ
## 取得解像度の設定
```.py
pipeline = rs.pipeline()
config = rs.config()
config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)
config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)
pipeline.start(config)
```

## 深度取得@(x, y)
```.py
frames = pipeline.wait_for_frames()
depth_frame = frames.get_depth_frame()
dist = depth_frame.get_distance(x, y)
```
zplugの設定要点と参考サイトの紹介

## zplugに乗り換えました
[こちら](https://qiita.com/mitsuhiro_K/items/248f0aa7ca0bfe194f78)の記事で、ターミナル周りの設定を書きました。
ですが、[zplug](https://github.com/zplug/zplug)を薦められたのでoh-my-zshから乗り換えました。

## 導入の参考にしたサイト
- [zplugで管理するzsh環境](https://qiita.com/sayama0402/items/adc1980b83d16c9a9bb0)

- [zplugの導入 oh-my-zshのような設定にするまで。](https://qiita.com/Jung0/items/300f8b83520e56766f22)

## 導入の要点
- .zshrcのバッグアップ作成
- oh-my-zshのアンインストール
- zplugのインストール
- .zshrcの変更
- source ~/.zshrcでプラグインのインストール

## 導入して感じたメリット
- インストールが早い
- 起動が早い

今の所この二つです。
シンプルに必要なプラグインだけインストールしているので、軽いのではないか？と思ってます。
公式にもメリットたくさん書いてあります。全ての恩恵を受けるには、もうちょっと踏み込んで使い倒す必要がありそうです。

## 設定について
[suinさんの.zshrcのプラグイン](https://github.com/suin/dotfiles/blob/master/.zshrc)を参考にしながら、そもそものzshの設定を追加していきました。
pecoに近いhistoryの検索や、up-arrowでの部分一致検索、tab補間など
一通り、ストレスのない設定にできました。

便利な設定等ありましたら、追加していきます。

### 参考一覧
- [zplugで管理するzsh環境](https://qiita.com/sayama0402/items/adc1980b83d16c9a9bb0)
- [zplugの導入 oh-my-zshのような設定にするまで。](https://qiita.com/Jung0/items/300f8b83520e56766f22)
- [suinさんの.zshrc](https://github.com/suin/dotfiles/blob/master/.zshrc)
- [日本語ドキュメント](https://github.com/zplug/zplug/blob/master/doc/guide/ja/README.md)
- [zshの補完を強化するTips](https://qiita.com/syui/items/ed2d36698a5cc314557d)
- [めんどくせーからzshrcそのまま晒す](https://qiita.com/kotashiratsuka/items/ae37757aa1d31d1d4f4d)
- [Zsh 補完をカーソルで選択する](http://kaworu.jpn.org/kaworu/2012-04-17-1.php)
- [up arrow completion(up-line-or-history) doesn't work](https://github.com/zsh-users/zsh-autosuggestions/issues/80)
AndroidのTextViewのフォントサイズを自動調整する

## 経緯
iOSではかなり昔からあった（気がする）TextView系のフォントサイズ自動調整機能。
Androidでも当然オプションとしてあるだろーと調べてみると意外にもAndroid 8.0 (API level 26) から対応したとのこと。
割と最近の話じゃないかと思った&微妙にはまったのでメモ。

## Autosizing TextViewsを使う
Android 8.0 (API level 26) からAutosizingTextViewが追加になりました。xmlにandroid:autoSizeTextTypeを追加します。

```xml
<TextView
    android:layout_width="match_parent" 
    android:layout_height="200dp"
    android:autoSizeTextType="uniform"
    app:autoSizeMinTextSize="12sp"
/>
```
計二回動かない問題にぶち当たりました。

### 駄目だったやつ
```xml
<TextView
    android:layout_width="wrap_content" 
    android:layout_height="200dp"
    android:autoSizeTextType="uniform"
/>
```
上記の問題点は二つです。
まずひとつめ、android:layout_widthにwrap_contentを指定していること。
公式にもちゃんと書いてあるのですが、wrap_conttentを使用する場合は期待通りに動かないかもね、らしいです。
>Note: If you set autosizing in an XML file, it is not recommended to use the value "wrap_content" for the layout_width or layout_height attributes of a TextView. It may produce unexpected results.

そしてふたつめ、app:autoSizeMinTextSizeを指定していなかったこと。
これもそれとなーく公式に書いてあります。
>Set autoSizeMinTextSize, autoSizeMaxTextSize, and autoSizeStepGranularity attributes to define the dimensions for the autosizing of TextView.

## 結論
リファレンスはちゃんと読みましょう。。。

## おまけ（API26より以前のバージョンの対応の場合）
```xml
<android.support.v7.widget.AppCompatTextView
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:autoSizeTextType="uniform"
    app:autoSizeMinTextSize="12sp"
/>
```
######あるならもっと早く対応してくれても良いのでは
## 参考
* https://developer.android.com/guide/topics/ui/look-and-feel/autosizing-textview
* http://beanidealisticrealist.hatenablog.com/entry/2018/02/12/210000
MSX PCGアニメ (2)

矢印キーでウェイト変更、スペースキーでキャラ追加。

```walk.c
/*
z88dk / WebMSX
zcc +msx -lndos -create-app -bnwalk walk.c
*/

#include <msx/gfx.h>
#include <stdlib.h>
#include <string.h>

#define BYTE unsigned char
#define WORD unsigned int
#define HIWORD(w) ((w)>>8)
#define LOWORD(w) ((w)&0xff)
#define _countof(arr) (sizeof(arr)/sizeof(arr[0]))

const BYTE space[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
const BYTE wall[8] = { 0xfe, 0xfe, 0xfe, 0x00, 0xf7, 0xf7, 0xf7, 0x00 };
const BYTE human[][8] = {
	{ 0x18, 0x58, 0x7e, 0x19, 0x18, 0x24, 0x22, 0x20 },
	{ 0x18, 0x1a, 0x7e, 0x98, 0x18, 0x24, 0x44, 0x04 }
};

BYTE vvr[32*24];	// 仮想VRAM
BYTE anim[8][8*9];	// アニメ phase, byte * name

void put_name(x, y, n)
{
	vvr[y*32+x] = n;
}

void gen_map()
{
	for (int x = 0; x < 32; x++) {
		put_name(x, 0, 1);
		put_name(x, 23, 1);
	}
	for (int y = 0; y < 24; y++) {
		put_name(0, y, 1);
		put_name(31, y, 1);
	}
}

void gen_anim()
{
	for (int ph = 0; ph < 8; ph++) {
		BYTE *dst = &(anim[ph]);
		BYTE *src = &(human[ph & 1]);
		memcpy(dst, src, 8);	// 0:待機
		memcpy(dst+8*1+ph, src, 8);	// 1,2:上->下
		memcpy(dst+8*4-ph, src, 8);	// 3,4:上<-下
		for (int y = 0; y < 8; y++) {
			WORD w;
			w = src[y] << (8-ph);	// 5,6:左->右
			dst[8*5+y] = HIWORD(w);
			dst[8*6+y] = LOWORD(w);
			w = src[y] << ph;	// 7,8:左<-右
			dst[8*7+y] = HIWORD(w);
			dst[8*8+y] = LOWORD(w);
		}
	}
}

void upd_map()
{
	static const BYTE updtbl[] = { 0,2, 2,0, 0,2, 2,0 };
	BYTE *p;

	// 3 6 7 10->0, 4 5 8 9->2
	p = vvr + 33;
	for (int i = 0; i < 702; i++) {
		if (*p > 2) {
			*p = updtbl[(*p)-3];
		}
		p++;
	}

	// キャラ追加
	if (get_trigger(0)) {
		BYTE *p = vvr + (33 + rand() % 702);
		if (*p == 0) {
			*p = 2;
		}
	}

	// 2->移動試みる
	p = vvr + 33;
	for (int i = 0; i < 702; i++) {
		if (*p == 2) {
			switch (rand() & 3) {
			case 0:
				if (*(p+32) == 0) {
					*p = 3;
					*(p+32) = 4;
				}
				break;
			case 1:
				if (*(p-32) == 0) {
					*(p-32) = 5;
					*p = 6;
				}
				break;
			case 2:
				if (*(p+1) == 0) {
					*p = 7;
					*(p+1) = 8;
				}
				break;
			case 3:
				if (*(p-1) == 0) {
					*(p-1) = 9;
					*p = 10;
				}
				break;
			}
		}
		p++;
	}
}

void main()
{
	const BYTE *pjiffy = (BYTE *)0xfc9e;

	int wait = 1;
	int count = 0;
	int phase = 0;

	set_mode(mode_1);
	gen_map();
	gen_anim();

	// キャラ投入
	put_name(10, 10, 2);

	vwrite(space, 0, 8);
	vwrite(wall, 8, 8);
	vwrite(vvr, 0x1800, 768);

	for (;;) {
		int st = get_stick(0);
		if (st) { wait = st; }

		BYTE jiffy = *pjiffy;
		while (jiffy == *pjiffy) ;

		if (++count >= wait) {
			count = 0;
			vwrite(&(anim[phase]), 16, 8*9);
			if (phase == 0) {
				vwrite(vvr+33, 0x1800+33, 702);
			}
			if (++phase >= 8) {
				phase = 0;
				upd_map();
			}
		}
	}
}
```

[WebMSX テープ版](http://webmsx.org/?tape=http://www.maroon.dti.ne.jp/lance/file/walk3.cas)
Homebrew で Python 3.6 を入れる

Python 3.7 がリリースされたので、Homebrew で入る `python3` のバージョンが 3.7.0 になった。
しかしまだ対応していないモジュールがいくつかあるので、ひとまず 3.6 を使い続けたい。

Homebrew で Python バージョンを指定してインストールする方法は無さそうだったので、以下のようにやる。

``` console
$ brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/f2a764ef944b1080be64bd88dca9a1d80130c558/Formula/python.rb
```

`f2a764e...` は Homebrew の Formula が Python 3.7 にバージョンアップされるひとつ前のリビジョン。

[History for Formula/python.rb - Homebrew/homebrew-core](https://github.com/Homebrew/homebrew-core/commits/master/Formula/python.rb)

しかしひとつ問題があって、Homebrew で入る `awscli` が Python 3.7 に依存している・・・。
Python 3.7 を消してこの方法で 3.6 を入れると、今度は awscli が動かない。

面倒なのでひとまず放置しているが、多分 awscli もリビジョンを指定してインストールすれば動くのじゃないだろうか。
VS Code1.25の気になった新機能(まとめ&小ネタ)

[Visual Studio Code](https://code.visualstudio.com) の バージョン 1.25 がリリースされたので、[リリースノート](https://code.visualstudio.com/updates/v1_25)を眺めてみて気になった機能をチェックしてみた。(以前のバージョンを眺めてみた時のやつはこちら。[1.24](https://qiita.com/12345/items/935770c6a3515ca80472) / [1.23](https://qiita.com/12345/items/627298550aab19f1d8a6) / [1.22](https://qiita.com/12345/items/8253a1eee38b6741905e) / [1.21](https://qiita.com/12345/items/71ce73c52cf2232fc10c) / [1.20](https://qiita.com/12345/items/1390c7cab11d968e7691) / [1.19](https://qiita.com/12345/items/a331c014a9d3fa9dac0e) / [1.18](https://qiita.com/12345/items/9b827138b5044ca82482) / [1.17](http://qiita.com/12345/items/28d83361341ce3ff3c9c) / [1.16](http://qiita.com/12345/items/5215293977dde2149c0f) / [1.15](http://qiita.com/12345/items/cebf4b4e9bfb2d2ef771))

# [グリッドエディタレイアウト](https://qiita.com/12345/items/41283e759e99ece85ced)
今回のリリースで一番の大ネタか。
これにより、エディタレイアウトの柔軟性が一気に増した！

# [アウトラインビュー](https://qiita.com/12345/items/103102dd379055987a0f)
たまに表示にまごつくことがあるが、VS CodeをIDE的に使いたい場合は欠かせない機能。

# [ポータブルモード](https://qiita.com/12345/items/5b056992a0d136a75697)
限定された環境でVS Codeを使いたい時に便利。

**以下、小ネタ集。**

# [空のエクスプローラへのドロップによるファイル・フォルダのオープン](https://code.visualstudio.com/updates/v1_25#_drop-files-and-folders-into-empty-files-explorer)
今までは、エディタエリアへのファイル・フォルダのドロップで開いたり、すでにファイル・フォルダを開いている状態でファイルエクスプローラにドロップすることで追加でオープンすることができたが、空のファイルエクスプローラに対するドロップには対応していなかった。それができるようになった。

# [履歴参照操作の統一](https://code.visualstudio.com/updates/v1_25#_history-navigation)
過去に入力した履歴を参照する際のキー操作は、検索フィールドの場合は`Alt`+`↑`/`↓`だったり、ターミナルの場合は`↑`/`↓`だったりしたのが今回`↑`/`↓`に統一された(今のところは`Alt`+`↑`/`↓`も引き続き使用可能)。
またこれにより、検索ビュー内でのフィールド間の移動キー操作が`↑`/`↓`から`Ctrl`+`↑`/`↓`に変更された(macOSの場合は`Cmd`+)。

# [ホバー表示の制御](https://code.visualstudio.com/updates/v1_25#_hover-display-options)
エディタ上でマウスカーソルを合わせた時に表示されるホバーの表示制御を行う設定が追加された。

- `editor.hover.enabled` ホバーの表示/非表示
- `editor.hover.delay` ホバー表示までの時間(ミリ秒)
- `editor.hover.sticky` ホバーにマウスカーソルを移動した時にホバーを表示し続けるかどうか

# [キャメルケース・スネークケース単位のカーソル移動](https://code.visualstudio.com/updates/v1_25#_subword-support)
キャメルケース・スネークケース単位でのカーソル移動や選択、削除をするコマンドが追加された。

- 左へ移動　`Ctrl` + `Alt` + `←`　cursorWordPartStartLeft
- 右へ移動　`Ctrl` + `Alt` + `→`　cursorWordPartRight
- 左へ選択　`Ctrl` + `Shift` + `Alt` + `←`　cursorWordPartStartLeftSelect
- 右へ選択　`Ctrl` + `Shift` + `Alt` + `→`　cursorWordPartRightSelect
- 左へ削除　`Ctrl` + `Alt` + `BS`　deleteWordPartLeft
- 右へ削除　`Ctrl` + `Alt` + `Delete`　deleteWordPartRight

が、残念なことに、最初の４つのコマンドについては既存のショートカットキーと被ってしまっていて、さらに最初の２つについては既存のほうが優先されてしまうので変更する必要がある。
あと、Windowsで`Ctrl`+`Alt`+`Delete`とか定義しちゃダメですから！！

# [拡張機能ビューの表示分類の変更](https://code.visualstudio.com/updates/v1_25#_new-default-view-for-extensions-view)
拡張機能ビュー内のビューの種類は以前は「INSTALLED」と「推奨」だったが、今回「有効」「推奨」「無効」に変更になり、インストール済みで無効になっている拡張機能が明確に分かるようになった。
ファイルの更新日時が更新されない

ファイルの更新日付が更新されない。
ファイルハンドルをつかみっぱなしで、ファイルの更新を行っている場合、
ファイルの中身に更新があったとしても、ファイルの更新日付は更新されない。

ファイルが閉じられると更新される。

この問題はOS側の問題。

https://blogs.technet.microsoft.com/asiasupp/2010/12/14/file-date-modified-property-are-not-updating-while-modifying-a-file-without-closing-it/