OmniAICreator/Qiita-1.07M huggingface dataset:
Windows10を買うときに気をつけたいこと（個人PC編）

# はじめに

ついに2020年1月14日にWindows7のサポートが切れてしまいます。
法人向けには有償で2023年までのサポートを受けることができますが、個人利用のPCはWindows10へ乗り換えなければいけません。

この記事では、個人PCでの乗り換えの選択肢となりうるであろうHomeとProについて書きます。
Qiitaを読まれている方はもう検討済みかもしれませんが...(汗

# Windows10のエディション

Windows10には用途に応じたエディションが用意されています。
PC向けには以下の4種類があります。

Home → 一般/個人/家庭向け
Pro → 企業向け
Enterprise → 大企業向け
Education → 学生/教師向け

# HomeとProどちらを選ぶか

## 価格差

２０１９年10月28日現在
Microsoft公式サイトでの価格差は約¥9,000ほど。この差はかなり大きいかと思います。

[Windows10 Home](https://www.microsoft.com/ja-jp/p/windows-10-home/d76qx4bznwk4?activetab=pivot:overviewtab)　¥19,360 (税込)
[Windows10 Pro](https://www.microsoft.com/ja-jp/p/windows-10-pro/df77x4d43rkt?activetab=pivot%3aoverviewtab)　¥28,380 (税込)

Amazonでは旧パッケージ版が安めで売られてたりします。
本当か嘘かはわかりませんが、レビューを見てるとニセモノ（？）が届くこともありそうなのでお気をつけください。

## 機能面

いろいろ機能面では異なる点はありますが５つに絞って挙げてみます。
基本的にはProエディションにしかない機能が欲しい場合はProエディションの購入を検討するべきかとは思います。

### ① リモートデスクトップ

Proエディションではリモートデスクトップのホストとして利用可能です。
別のマシンやタブレットなどからProエディションのマシンを操作することができます。（VPN等を導入すれば外出先からでも可能です。）

RDPWrapperLibraryやTeamViewer、Googleリモートデスクトップなどを使えばHomeエディションであってもリモートデスクトップを利用すること自体は可能です。
ただ、これらはMicrosoft製のものではなくサードパーティ製のソフトウェアですので利用には注意が必要かと思います。

### ② 仮想化関係

ProではVHD(仮想ハードディスク)からのOS起動やHyper-Vでの仮想マシンが利用可能です。

Hyper-Vに関してはVMWareやVirtualBox等で似たようなことはできますが、仕組みとしては異なるもののようですのでこれらはProエディションの利点であるかと思います。

### ③ ドメイン参加とグループポリシー

Homeエディションではこれらの機能は利用できません。
ネットワーク内のPCがドメイン参加とグループポリシーで管理されているなどがあればProを選ぶ必要があるかと思います。

### ④ セキュリティ

ProエディションではBitLockerという機能が使えます。
HDDやSSD、DVDやUSBメモリなどの内容を暗号化してセキュリティを確保する機能です。
完全にとはいきませんが、ある程度セキュリティを確保することができるようです。

### ⑤ WindowsUpdateの自動更新

Proエディションでは自動でアップデートされるのではなく任意のタイミングに変更ができます。
Homeだと定期的にアップデートの再起動を要求されることや、バックグラウンドで更新されていて作業の邪魔などでストレスが溜まることがあるかと思います。

※ WindowsUpdateを無視して放っておいて良いということではありません。アップデートは早めに行うようにしましょう。

# Windows10の販売形態

Windows10の販売形態は4種類あります。
基本的には、パッケージ版を購入するのが良いかと思います。

たまにオークションサイトなどで激安のWindowsが売られていますが、これら正規品でないことがほとんどです。
OME版やVL版だったとしてもライセンス違反になりうるので買わないようにしましょう。

### パッケージ版

通常販売品で、4種類の中で一番制約が少ないです。
マシンの構成が変わってもライセンスの認証が可能です。（マシンを一新しても同じプロダクトキーでWindowsをインストールできます。）
ライセンスはMicrosoftアカウントに紐づきます。
自作erでもよく組み替える方だとこちらのほうが良いです。

### DSP版

PCパーツにセットで販売されます。自作マシン向けです。
Homeエディションだとパッケージ版との差はそれほどありませんが、Proエディションではそこそこ差があります。
ただ、DSP版の制約として
・ パーツとセットで販売されること
・ ライセンス認証回数が決まっていること
・ ライセンスはマザーボードに紐づくこと（他のパーツを変えたら再認証が必要になったという話も）

### OME版

PCベンダーが使う用です。。個人で買うことはないと思って良いです。

### VM版

企業向けで一つのプロダクトキーで複数のマシンにインストールできます。これも個人で買うことはないと思って良いです

# さいごに

基本的には機能面や用途に合わせて選んだり、予算で選べば問題ないかと思います。

私個人としては、Windows10のPCを買う場合はProエディション、OS単体で買う場合はパッケージ版のProエディションをおすすめします。
一般向けに販売されるPCのほとんどはHomeエディションではありますが、購入時にOSを選択できる場合もありますので選んでみてください。
docker-compose.ymlを書いたらチェッカー入れてみようねって話

# なんか怒られるようになった・・・

```
services.web.environment.ports contains ["3000:3000"], which is an invalid type, it should be a string, number, or a null
```

書いてるのはお馴染みの下記の記述。

```
ports:
  - 3000:3000
```

妙なのはdbコンテナでは上記で書けて、webコンテナでは書けないと言うこと。

##　原因解明

質問したら、ワンパンで解決。

>　インデントずれてね？

そう、インデントがずれていたのである。私のエディタでは全角のインデントを可視化させているので、視覚的に妙なインデントになるのを防ぐようにしてて安心しきってたんですが、純粋に階層が１つ深くなった状態になってたんですね。

```docker-compose.yml
  web:
    build: .
    command: ["/bin/sh", "-c", "yarn install && cd product_name && bundler exec rails s -p 3000 -b '0.0.0.0'"]
    environment:
      BUNDLE_APP_CONFIG: /web/.bundle
      ports:
       - 3000:3000
      depends_on:
       - db
```

上記のようになったたんですね。正解は、下記です。

```docker-compose.yml
  web:
    build: .
    command: ["/bin/sh", "-c", "yarn install && cd product_name && bundler exec rails s -p 3000 -b '0.0.0.0'"]
    environment:
      BUNDLE_APP_CONFIG: /web/.bundle
    ports:
      - 3000:3000
    depends_on:
      - db
```

いやー、微妙。すごい見つけずらい。でもこうしないと、ymlの記述の型がおかしくて怒られるようになるので、注意しないといけないです。で、オススメされたのがこちら。

[code-beautify](https://codebeautify.org/yaml-to-json-xml-csv)

これのyamlチェッカーを使うと、ミスが減るんじゃないでしょうかとのこと。確かにその通りなので、以降使っていきたいと思います。
HerokuでServer Error 500 が出て数日悪戦苦闘したが解決したケアレスミス

# 背景
DjangoでWEBアプリを開発していました。
ローカルで仮想環境を作って、Herokuにデプロイしていましたが、ある日突然サーバーエラー500。
特定のページだけだったのですが、どうにもこうにも原因が分からず、1，2週間ほど放置してしまいました。。

どこかの記事で、settigns.pyの中で、

```
DEBUG = TRUE
```
で一度でもデプロイをしたらサーバーエラーが出続けるというのを見つけたのですが、それが事実であれば、データベースの内容を移行させなくてはならなくなり、面倒です。。。

# Herokuのサーバーエラー500は厄介

何が厄介かというと、エラーの種類によっては、
- ローカルではエラーにならない
- heroku のログを見てもserver error 500 以外のことが分からない
からなのです。

# 原因は

原因はいたって簡単。CSSやJSを読み込むところがリンクエラーになっていました。

```
<link rel="stylesheet" href="{% static 'css/●●●.css' %}">
<script src="{% static 'js/●●●.js' %}"></script>
```

↑です。

エラーになったページをローカルで開いて、ソースを読み込んだらすぐにわかりました。

はまってしまったので、備忘録として残しておきます。
AWSクラウドプラクティショナー 受験記録

# AWS クラウドプラクティショナーを受けたので勉強した内容と方法を残します
勉強期間2週間くらいでクラウドプラクティショナー受けました。
ご参考まで。

## 前提知識の有無
AWSは遊びでアカウント登録したくらい。
特に何も触ってません。
EC2、SQS、S3くらいは知ってたかな。

## 教材
-  [参考書](https://www.amazon.co.jp/AWS%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-AWS%E8%AA%8D%E5%AE%9A-%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%BC-%E5%B1%B1%E4%B8%8B-%E5%85%89%E6%B4%8B-ebook/dp/B07QX45RXM/ref=tmm_kin_swatch_0?_encoding=UTF8&qid=1572229091&sr=8-1) 
とりあえず買ってみただけですが、結構まとまっていてよかったです。
読み物として１週、問題だけ解く形でもう１週。計5時間くらい。

- [ホワイトペーパー(アマゾン ウェブ サービスの概要)](https://d1.awsstatic.com/whitepapers/ja_JP/aws-overview.pdf?did=wp_card&trk=wp_card) 
とりあえずサービス名を覚えましょう。
上から下まで１回読んで、受験前にもう１回舐めれば大体OK。

- [ホワイトペーパー(AWS Well-Architected フレームワーク)](https://d1.awsstatic.com/whitepapers/ja_JP/architecture/AWS_Well-Architected_Framework.pdf?did=wp_card&trk=wp_card)
AWSの各サービスを組み合わせる際の考え方が書いてあります。
試験で問題読むときに前提とされている内容なので、理解はしましょう。
大した事ないです。冗長に組めよ。スケーラブルにするのよ。極力お安くね。って書いてあるだけ。

- [AWS Cloud Practitioner Essentials](https://www.aws.training/Details/Curriculum?id=34408)
AWSが提供してくれているお勉強動画。

## やったこと
1. ホワイトペーパーをさらっと眺める。 　
概要とアーキテクチャ。2～3時間もあれば読めます。
とりあえず名前と出来ることくらい憶えておきましょう。
試験では地味にサービス名を選ぶだけの問題も出ました。snowmobileとか。。。

2. 白本を読む
大体4時間くらいで読めました。
ホワイトペーパーで出てきたサービス名をくっつけて雰囲気を掴む感じ。
白本読んでてよかったなー。と思ったのは請求回り。
技術屋さん的にはほぼ興味ないんだけれども、問題としては割と出るので注意。

3. お勉強動画見る。
全部で6時間以上あるので思った以上に苦痛。
でも、まぁ通過儀礼と思って観ましょう。
ここで、これ全然しらねーわ。とか思うところがあったら白本読むなりググるなりしましょう。

4. 試験当日。
白本の章末問題だけをつらっと舐める。
ホワイトペーパーのサービス名を一通り見返す。
上記だけやって受験。

## 結果
平日は1日2時間。試験前日と当日午前で詰込みした結果、無事合格。
ちなみに合格時の点数は913/1000点。(合格ラインは700点)

## 感想
実は参考書が思ったより早く読み終わったので同じシリーズのアソシエイトも買ってみたりしました。
中身も一通り読んだのですが、クラウドプラクティショナーとアソシエイトでは視点が違う感じがしました。
クラウドプラクティショナーは本当にプリ向けというか、費用面やAWSのメリデメの話。アソシエイトはサービスの中の話というか。そんなイメージでした。
なので、いやーAWS触ったことないんだけどねー。みたいな人もプラクティショナーであれば気負わずに受けても大丈夫かと。

以上。
php7.1から使える負の文字列オフセット

php7.0以前までは、
```$str[3]``` のように、 角括弧を使用してゼロから始まるオフセットを指定すると、
文字列内の任意の文字を取り出すことが可能でした。 

ただ、php7.1からは負の値のオフセットも指定できるようになりました。

> 注意: PHP 7.1.0 以降では、負の文字列オフセットにも対応するようになりました。 これは、文字列の末尾からのオフセットを表します。 以前のバージョンでは、負のオフセットで読み込もうとすると E_NOTICE が発生し (空文字列を返します)、負のオフセットで書き込もうとすると E_WARNING が発生していました (文字列には何も手が加えられません)。

```php
var_dump("abcdef"[-1]);
var_dump("abcdef"[2]);
var_dump("abcdef"[-3]);
```

```
出力結果
ーーーーー

string(1) "f"
string(1) "c"
string(1) "d"
```

単一文字の場合はsubstr()を使う必要がなくなりそうです。
複数の文字を取り出したり変更したりしたいときは、substr()を使用すればよいです。
ただ、個人的には第三者への可読性という意味ではsubstr()を使ってもいいのかと思います。
VSCodeの拡張機能を作ってみる

# はじめに
コマンドプロンプトで実行していた開発支援ツール（コマンドラインツール）を、拡張機能を作ってVSCode統合してみる。
（統合する開発支援ツールは、node.jsで作成されたコマンドラインツール）

まずは、VSCodeで動作するものを作り、その後、code-serverやEclipse theiaでも動作させたい。

【参考】[code-server](https://github.com/cdr/code-server)
【参考】[Eclipse theia](https://github.com/eclipse-theia/theia)

# 開発環境
||バージョン|
|---|---|
|OS|Windows 10|
|VSCode|1.39.2|
|node.js|v12.6.0|
|npm|6.9.0|

# VSCode拡張機能「HelloWorld」

拡張機能の作成方法は、ググるとたくさんヒットするので、いろいろと参考にさせていただいた。

まずは、yoとgenerator-codeをインストールする。

```
> npm install -g yo
> npm install -g generator-code
```
そして、コード生成を実行

```
> yo code
```
いろいろと尋ねられるが、「New Extension (JavaScript)」を選択し、拡張機能の名前、拡張子、説明などを入力すると、コードが生成された。

# 生成されたコードの確認

extension.js
(コマンド登録部分「extension.helloworld」)
![extensions.js.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517406/5fea7e9d-5f47-7d02-5f64-d5f5ffb561dd.png)

launch.json
(デバッグ実行の設定)
![launch.json.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517406/84e8a7a9-5943-e07f-e4a9-aaa0b76339e8.png)

package.json
(コマンドパレットには「Hello World」と表示される)
![package.json.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517406/4aa036ca-b7ee-61fa-aca2-47c89468b915.png)


# 実行してみる
実行ボタンを押す。
![run_extension.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517406/b4af2c2c-1cc5-e6f3-ff9c-f64032c54ccb.png)

VSCodeがもうひとつ立ち上がる。
![new_vscode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517406/73e100b7-e49a-87d0-162b-dccfd60417dd.png)

新しく立ち上がったほうのVSCodeで、コマンドパレットを表示(Ctrl + Shift + P)して、コマンドパレットに「Hello World」と入力しenterを押す。
![command_palette.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517406/a5d3b713-c935-5f50-9539-83f25f884a8b.png)

「Hello World!」がポップアップ表示されました。
![HelloWorld.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517406/bac865d3-a09a-9188-8e61-25b469f5d967.png)

# 次回予定
少しこのサンプルをいじってみる。または、このサンプルをcode serverとか、Eclipse Theiaでも動くかを確認する。
ユーザー新規登録備忘録 part3：遷移元のコントローラーとアクションを取得して、条件分岐をする

# ~同じコントローラーのアクションを使って今いるページからのリンク先を変える方法~
## 起きていたこと

### 1.新規登録の時(修正前)
#### /signup/cards
![cards.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487723/053667ee-f981-0b33-dcb3-f667afd6cc32.png)
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
#### /card/show
![show.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487723/08876905-0155-fb5e-95e3-7c629bc0df33.png)

### 2.カード情報を追加登録の時(修正前)
#### /card/new
![new.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487723/ddfcb2b4-670d-5dd2-a48a-fecdeabd19ca.png)
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
#### /card/show
![show.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487723/08876905-0155-fb5e-95e3-7c629bc0df33.png)

## "1.新規登録"の時の遷移先を/signup/finishにしたいが<br>問題のコントローラーを確認すると/signup/finishに飛んでない!!**
  ~~~rb:card_controller.rb(修正前)
  def pay 
    Payjp.api_key = ENV["PAYJP_ACCESS_KEY"]
          [省略]
      if @card.save//保存できたら
        redirect_to action: "show"//カード情報を表示する
      else//保存できなかったら
        redirect_to action: "pay"
      end
    end
  end
  ~~~


##やりたいこと
**/signup/finishを設定してない遷移元のコントローラーとアクションを指定して条件分岐できないだろうか？**
**=>会員登録の時とユーザー設定ページのそれぞれでcardコントローラーでnewを使用したした時で分けたい**
![理想形.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487723/00a3520f-d91b-16e1-55d2-c1990d295cc3.png)


## 結論:request.referrerを使用する
~~~rb:request.referrerの例
遷移元のコントローラーを取得
Rails.application.routes.recognize_path(request.referrer)
　{:controller=>"users", :action=>"index"}

こちらで遷移元の URL が取得できる
request.referrer
　"http://localhost:3000/users"
~~~
=========================================

### request.referrerを実装する
  ~~~rb:card_controller.rb(修正後)
  def pay 
    Payjp.api_key = ENV["PAYJP![cards.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487723/8eae145d-f132-acff-0c61-a44229d99489.png)
_ACCESS_KEY"]
          [省略]
       path = Rails.application.routes.recognize_path(request.referer)
        if path[:controller] == "card" && path[:action] == "new" //もしも、"card"コントローラでnewを行ったら、
          redirect_to action: "show"　//showを行う
        else　//違ったらfinishへ飛ばす
          redirect_to finish_signup_index_path
        end
          [省略]
  ~~~

## 修正した結果
### 1.新規登録の時（修正版）
#### /signup/cards
![cards.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487723/053667ee-f981-0b33-dcb3-f667afd6cc32.png)
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
#### /signup/finish
![finish.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487723/9fedfd93-d72c-92c2-5f14-9efe0e363fc6.png)
falseで読み込まれるため/signup/finishへ飛ぶ

~~~rb:実行したところ
        else　//違ったらfinishへ飛ばす
          redirect_to finish_signup_index_path
~~~
### 2.カード情報を追加登録の時
trueのためこちらの結果は修正前と変わらない

##### 参考記事
https://qiita.com/sayama0402/items/ffe96ff76148231a0c22
http://kawahiro.hatenablog.jp/entry/2014/03/21/164449
vagrant upが出来ない→Bringing machine 'default' up with 'virtualbox' provider...

# vagrant upが出来ない

error内容

```
Bringing machine 'default' up with 'virtualbox' provider...
A VirtualBox machine with the name 'my-app' already exists.
Please use another name or delete the machine with the existing
name, and try again.
```

調べると`vagrant destroy`しろという記事ばかり…
消したくないんだよね。。。

## 解決策

vmのidを表示

```
$ vboxmanage list vms
"my-app" {3fdsaaeb-066a-417c-b62a-3563fv5c34068}
```

.vagrant以下のこのファイルに上記idを書き換える
`~/.vagrant/machines/default/virtualbox/id`

```
3fdsaaeb-066a-417c-b62a-3563fv5c34068
```

## なぜ起こったのか？
.vagrant以下を書き換えてしまったのかも知れない？？
WRF > v3.7.1とv4.1.1(v4.1.2)のnamelist.input.4kmの差分

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2 
32GB RAM 
CentOS Linux release 7.7.1908 (Core)
```

WRF (Weather Research and Forecasting Model)関連。

v3.7.1からv4.1.1へ変更する場合、どのような設定変更が必要となるのか。

namelist.input.4kmの差分を取ってみた。

```
10,11d9
<  start_minute                        = 00,   00,   00,
<  start_second                        = 00,   00,   00,
16,17d13
<  end_minute                          = 00,   00,   00,
<  end_second                          = 00,   00,   00,
23c19
<  restart_interval                    = 5000,
---
>  restart_interval                    = 1440,
28d23
<  debug_level                         = 0
40c35
<  num_metgrid_levels                  = 40
---
>  num_metgrid_levels                  = 32
55c50
<  mp_physics                          = 6,     6,     6,
---
>  mp_physics                          = 8,     8,     8,
62a58
>  ysu_topdown_pblmix                  = 1,
65,66d60
<  isfflx                              = 1,
<  ifsnow                              = 0,
68,69c62
<  surface_input_source                = 1,
<  num_soil_layers                     = 4,
---
>  num_land_cat                        = 21,
76a70
>  hybrid_opt                          = 2, 
83c77
<  damp_opt                            = 0,
---
>  damp_opt                            = 3,
89,90c83,84
<  moist_adv_opt                       = 1,      1,      1,     
<  scalar_adv_opt                      = 1,      1,      1,     
---
>  moist_adv_opt                       = 2,      2,      2,
>  scalar_adv_opt                      = 2,      2,      2,
95,98c89
<  spec_zone                           = 1,
<  relax_zone                          = 4,
<  specified                           = .true., .false.,.false.,
<  nested                              = .false., .true., .true.,
---
>  specified                           = .true.,
```

### 変更点

- start_minute : ない                        
- start_second : ない
- end_minute : ない
- end_second : ない
- debug_level : ない
- num_metgrid_levels: 40 -> 32
- mp_physics: 6 -> 8
    - [Micro Physics Options (mp_physics)](http://www2.mmm.ucar.edu/wrf/users/phys_references.html)
    - 6: WRF Single–moment 6–class Scheme
    - 8: Thompson Scheme
- ysu_topdown_pblmix : 追加
- isfflx : ない
- ifsnow : ない
- surface_input_source : ない
- num_soil_layers : ない
- num_land_cat : 追加
- damp_opt : 0 -> 3
    - https://esrl.noaa.gov/gsd/wrfportal/namelist_input_options.html
    - 0: without damping
    - 3: with w-Rayleigh damping (dampcoef inverse time scale [1/s]  
        - e.g. 0.2; for real-data cases)
- moist_adv_opt : 1 -> 2
    - https://esrl.noaa.gov/gsd/wrfportal/namelist_input_options.html
    - moist_adv_opt (max_dom)
        - for moisture
    - 1と2の違いは下記資料のp11参照
        - https://pdfs.semanticscholar.org/249e/66ab69c8229c8c51f33bc9614e0ef0005bdb.pdf
- scalar_adv_opt : 1 -> 2
    - for scalars
- spec_zone : ない
- relax_zone : ない
- specified : ドメインごとの指定が一つの指定に？
- nested : ない


### 補足
(追記 2019-11-11)

v4.1.2とv4.1.1のnamelist.input.4kmを比較したが、差異はなかった。
Laravel Dusk + Selenium + Dockerでブラウザテスト（Laravel6.0）

Laravel6.0 + Docker開発環境でブラウザテストを自動化する方法について解説します。
前提条件として、LaravelのDocker開発環境が構築済みで、Laravelのウェルカムページにアクセスできる必要があります。

#開発環境
Laravel6.0
PHP7.3.10
macOS
Docker19.03.2
docker-selenium images:
　・selenium/hub:3.141.59-vanadium
　・selenium/node-chrome:3.141.59-vanadium
Google Chrome

#Laravel Duskのインストール
composer.jsonのrequire-devにLaravel duskを追加します。
(この時、requireの方に追加しないように注意しましょう。本番環境にDuskをインストールするとセキュリティ的によくないです。)

```json
"require-dev": {
        "laravel/dusk": "^5.5",
    }
```

　その後、`composer install`でライブラリをインストールしましょう。

#docker-seleniumでブラウザテスト用サーバーを立てる
docker-compose.ymlを編集します。

```yml

version: '3.7'

services:
  dev:
    build:
      context: "./docker/dev/"
    image: project/dev
    container_name: project-dev
    volumes:
      - "./project:/project"
    ports:
      - 8000:80
  
  selenium-hub:
      image: selenium/hub:3.141.59-vanadium
      container_name: selenium-hub
      ports: 
          - 4444:4444

  chrome:
    image: selenium/node-chrome:3.141.59-vanadium
    container_name: selenium-chrome
    volumes:
      - /dev/shm:/dev/shm
    depends_on:
      - selenium-hub
    environment:
      - HUB_HOST=selenium-hub
      - HUB_PORT=4444
```

#Laravel Duskの設定を行う。
`project/tests/DuskTestCase.php` を編集します。

```php
<?php

namespace Tests;

use Laravel\Dusk\TestCase as BaseTestCase;
use Facebook\WebDriver\Chrome\ChromeOptions;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Remote\DesiredCapabilities;

abstract class DuskTestCase extends BaseTestCase
{
    use CreatesApplication;

    public static function prepare()
    {
        // static::startChromeDriver();
    }

    protected function baseUrl(){
        return 'http://project-dev:80';
    }

    protected function driver()
    {
        $options = (new ChromeOptions)->addArguments([
            '--disable-gpu',
            '--headless',
        ]);

        return RemoteWebDriver::create(
            'http://selenium-hub:4444/wd/hub', DesiredCapabilities::chrome()->setCapability(
                ChromeOptions::CAPABILITY, $options
            )
          );
    }
}
```

デフォルトでは、`project/tests/Browser/ExampleTest.php`に書かれている以下のテストが実行されます。

```php
<?php

namespace Tests\Browser;

use Tests\DuskTestCase;
use Laravel\Dusk\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;

class ExampleTest extends DuskTestCase
{
    public function testBasicExample()
    {
        $this->browse(function (Browser $browser) {
            $browser->visit('/')
                    ->assertSee('Laravel');
        });
    }
}
```

これでブラウザテストの準備が整いました！！
早速コンテナを立ち上げ、`php artisan dusk`を実行してみましょう。
問題なくブラウザテストが通ったら完了です。
今更だけど Swift で Extensions を使って型を拡張してみる

## はじめに

Extensions によって、型を拡張することができます
https://docs.swift.org/swift-book/LanguageGuide/Extensions.html
２つサンプルを書いてみたので備忘録として載せます

### String型でIntチェックできるように拡張

```swift
//  String+checker.swift

import Foundation

extension String {
    /// "1" // true
    /// "Hello world" // false
    /// "" // false
    var isInt: Bool {
        return Int(self) != nil
    }
}


let hogeNumber: Int = 0
hogeNumber.isInt // true
```

### URL型でパラメータを受け取れるように拡張

```swift
//  URL+parameters.swift

import Foundation

/// URL型を拡張します
extension URL {
    /// 指定したURLクエリパラメーターの値を取得する
    /// - Parameter key: URLクエリパラメーターのキー
    /// - Returns: 指定したURLクエリパラメーターの値（存在しない場合はnil）
    func queryValue(for key: String) -> String? {
        let queryItems = URLComponents(string: absoluteString)?.queryItems
        return queryItems?.filter { $0.name == key }.compactMap { $0.value }.first
    }
}


http://nananana/hahahaha?param_id=5
let id = URL(string: url.absoluteString)?.queryValue(for: "param_id")
NGLog(id) // 5
```
Google App Scriptで自動でログ保存をする


スプレッドシート上でシート名'archive'に対し、1行目に最新データを毎日定期更新、その上でその1行目のデータを最終行に追加していく。


```js
function date_update() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName('archive');
  var lastrow = sheet.getLastRow();
  sheet.getRange(lastrow-1,6).copyTo(sheet.getRange(lastrow, 6), {contentsOnly:false});
}
```


```js
 function auto_archives() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName('archive');
  var lastrow = sheet.getLastRow() + 1;
  sheet.getRange("A1:E1").copyTo(sheet.getRange(lastrow, 1), {contentsOnly:true});
}
```

2020/07/13 1プロジェクトでもっと簡単に記載できる方法があったので追記

```js
function auto_archives() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName('archive');
  var sheet2 = ss.getSheetByName('data');
  var lastrow = sheet2.getLastRow() + 1;
  sheet.getRange(2,1,1,2).copyTo(sheet2.getRange(lastrow, 1), {contentsOnly:false});
}
```
ふりがな自動入力の効果を検証

# ふりがな自動入力を実装しました
このようなフォームで、お名前欄に漢字を入力すると、カナが自動で入ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69647/6c386c4f-eb83-6325-f57a-cdbf441e5a45.png)

苗字（漢字）：62クリック
苗字（カナ）：21クリック

3人に2人がカナ入力のテキストボックスをクリックしなくなりました。


名前（漢字）：47
名前（カナ）：26

名前は約2人に1人がテキストボックスをクリックしなくなりました。


苗字の補完精度は高いようですが
名前は特殊な漢字の人が多いので、カナ入力がうまくいかない確率が高いようです。


あまりにも、精度が低く、10人中9人が打ち直してるなら、削除する手間が面倒なので
名前だけ自動入力をしない方が良いのではとも思いましたが

2人に1人が自動入力でうまく入力できているのであれば自動入力はあった方が良いでしょう。
【JavaScript入門】ES2015の概要

## 参考書籍
* [WEB+DB PRESS Vol.87](https://gihyo.jp/magazine/wdpress/archive/2015/vol87)
* [Software Design 2019年3月号](https://gihyo.jp/magazine/SD/archive/2019/201903)
* [改訂新版JavaScript本格入門](https://gihyo.jp/book/2016/978-4-7741-8411-1)
* [初めてのJavaScript](https://www.oreilly.co.jp/books/9784873117836/)

## ES2015について

### ECMAScript
* ES6やES2015のESと言うのはECMAScriptの略
* ECMAScriptはEcma Internationalによって定められるJavaScriptの標準規格／言語仕様
* JavaScriptはECMAScriptの仕様に基づいた言語のひとつ

### 標準化
* どのようなプログラムを書いたらどのように動くのかを言語の仕様としてきちんと定義すること
* ブラウザごとに動作が違う問題を、どの処理系でも動作を同じにすることで解決することが目的

### ES2015で追加された構文
* **文字列のテンプレートリテラル**
* **let・constキーワードによる変数宣言（ブロックスコープ）**
* **関数の引数のデフォルトパラメータ**
* **関数の可変長引数**
* **アロー関数**
* ジェネレータ関数（停止や再開ができる特殊な関数）
* classキーワードによるクラス宣言
* importとexportによるモジュール構文
* 他にもArrayなどの既存のオブジェクトに対して様々な関数が追加され、機能が強化された

### ES2015に追加されたオブジェクト
* **Promise: 非同期処理を抽象化するデザインパターン**
* Symbol: ユニークな値を表現する新たなプリミティブ型
* Reflect / Proxy: オブジェクトの操作をカスタマイズするしくみ
* Set / WeakSet: 一意なデータスタックを表すオブジェクト
* Map / WeakMap: Key-Valueのデータ構造を表すオブジェクト

### その他関連項目
* トランスパイラ：新しいJavaScriptの記法を古いJavaScriptに変換するアプリケーション
* Polyfill：古いブラウザに対して新しい機能の代替的な実装を追加するスクリプト

ES6ポリフィルとは、ES6の新しい組込みクラスやメソッドを古い環境でも使えるようにJavaScriptで実装したライブラリ。ポリフィルで実現できることは限られるが、ビルドが不要なためトランスパイラより手軽に導入できる。

## テンプレート文字列

テンプレート文字列を利用することで、以下のような文字列表現が可能になる。

* 文字列への変数の埋め込み
* 複数行にまたがる（＝改行文字を含んだ）文字列

```javascript:script.js
let name = '鈴木';
// テンプレート文字列では、「\`」（バッククォート）で文字列をくくる
let str
  = `こんにちは、${name}さん。
  今日も良い天気ですね！`;
//改行文字を、テンプレート文字列ではそのまま表現
console.log(str);
```

## 定数
* ES2015で標準化された（以前は一部のブラウザーによる拡張仕様）
* 単語をアンダースコアで区切るのが一般的
* 定数を利用することで値の意味が明確になり、コードの可読性が増す
* 修正箇所が一箇所になり、修正漏れを未然に防ぐことができる

```javascript:script.js
const TAX = 1.08;
var price = 100;

console.log(price * TAX); // 108
```
Phoenix用Dockerfile

落ち着いてきたのでPhoenixにしっかり入門しようと思いPhoeinxの環境を構築してみた。
以前、雑にGKEに乗っけるための記事を書いたりしたがそこから期間が空いてしまいPhoenixに関するいろいろな記憶が失われていたため再構築中
今回は手元にDockerを使ってPhoenixの開発に必要な環境を構築したので備忘録とす

## 想定読者

* [ ] ぼく
* [ ] Phoenixを追いかけ始めた新米錬金術師

## Dockerfile

早速ですが試行錯誤の末に完成したDockerfileです

```dockerfile
FROM elixir:1.9.0

WORKDIR /app

RUN apt-get update && \
  curl -sL https://deb.nodesource.com/setup_10.x | bash - && \
  apt-get install -y nodejs npm inotify-tools

RUN mix local.hex --force && \
  mix archive.install --force https://github.com/phoenixframework/archives/raw/master/phx_new.ez && \
  mix local.rebar --force

COPY mix.exs mix.exs
COPY mix.lock mix.lock
RUN mix deps.get && mix compile

COPY assets/package.json assets/package.json
COPY assets/package-lock.json assets/package-lock.json
RUN cd assets && npm install

EXPOSE 4000
COPY . .
```

ポイントはDockerfileの時点で `mix deps.get && mix compile`していること
これしとくことでKubernetesに乗っけたときも即起動するはず...たぶん(動かしてない)

## docker-compose.yml

こちらも早速

```yaml
version: '3.2'
services:
  app:
    build: .
    ports:
      - "4000:4000"
    command: tail -f /dev/null # 開発用なのでコンテナ内でiex -S mix phx.serverする前提
    environment:
      - MIX_ENV=dev
      - PORT=4000
      - DATABASE_USER=postgres
      - DATABASE_PASSWORD=postgres
      - DATABASE_NAME=postgres
      - DATABASE_HOST=db
      - DATABASE_URL=ecto://postgres:postgres@db/postgres # NOTE: これはproductionで動かすときに使う
      - SECRET_KEY_BASE=
    volumes:
      - .:/app
    depends_on:
      - db
  db:
    image: postgres
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_HOST=db
      - POSTGRES_DB=postgres
```

先に書いたDockerfileを使ってローカルで開発するとちょっとボリュームの共有がやりづらくなってしまう(´・ω・｀)
これはDockerfile内でassetsとpackageをコンパイルしているがローカルには存在しないため手元のコードをマウントすると_buildとassetsの成果物が失われるため(´・ω・｀)
ただ、ローカル開発だけならパッケージを追加しない限りは一度 `mix compile`しておけば再コンパイルの必要はない。assetsも同じ


## 最初にやること

```bash

docker-compose pull
docker-compose build
docker-compose up -d
docker-compose exec app bash -c "cd assets && npm install"
docker-compose exec app mix deps.get && mix compile
```

↑のコードを順次実行することでローカル開発の準備完了

## さいごに
これで手元のコードを編集して普段どおりに開発するだけで問題ないはず
Dockerfileの内容的にはKubernetesにデプロイしてもデプロイ後からmix compileが始まるみたいなことは起きないはずなので
安心して運用できる気がします(未検証)
LaravelのSeederはFactory使うとリレーションしてても簡潔にかける

# Seederとは
データベースにあらかじめデータが欲しい時に、Seederを使用すれば楽に用意ができる

# Factoryとは
Factoryを使用すると意図したModelのデータを定義しておけば、任意のタイミングでFactoryを使えばModelインスタンスを呼び出せる。テストやSeederを使用するときに利用する

# FactoryをSeederで使用する
FactoryをSeederで使用すると複数データを用意する場合にfor文を書かなくていいので、簡潔にコードが書ける。いくつかRelationがあっても簡潔に書ける。

## 仮のモデルのコード

``` php
namespace App;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    protected $fillable = [
        'title', 'content',
    ];

    public function post_images()
    {
        return $this->hasMany(PostImage::class, 'post_id', 'id');
    }

    public function user() {
        return $this->belongsTo(User::class);
    }
}
```
1対多でPostImage、多対1でUserとRelationを設定してある


## Factoryを作成する

- 1. artisanコマンドの実行

``` bash
php artisan make:factory PostFactory
```
database/factoriesにPostFactory.phpが作成される

- 2. PostFactory.phpの編集

```php

use Faker\Generator as Faker;

$factory->define(App\Post::class, function (Faker $faker) {
    return [
        'title'   => $faker->realText(100),
        'content' => $faker->realText(3000)
    ];
});]
```
Fakerを使ってFactoryでModelを生成する際の標準のダミーデータをセットできる

## Seederを作成する

- 1. artisanコマンドの実行

``` bash
php artisan make:seeder PostsTableSeeder
```
database/seedsにPostsTableSeeder.phpが作成される

- 2. PostsTableSeeder.phpの編集

```php
use Illuminate\Database\Seeder;

class PostsTableSeeder extends Seeder
{
    public function run()
    {
        // factoryを利用
        factory(App\Post::class, 10)
            ->create(['title' => 'test'])
            ->each(function(App\Post $post) {
                $post->post_images()->saveMany(factory(App\PostImage::class, 3)->make());
                $post->user()->associate(factory(App\User::class)->create());
            });
        
        // factoryを利用しない場合(Relationはめんどいので省略)
        $faker = Faker::create('ja_JP');

        for ($i = 1; $i <= 10; $i++) {
            Post::create([
              'title' => $faker->realText(100),
              'content' => $faker->realText(3000)
            ]);
        }
    }
}
```
factoryメソッドで生成するModelと個数を指定して、ModelのCollectionをcreateする
createするときにPostFactoryで指定した値をパラメーターごとに変更が可能
Collectionのeachを呼ぶことで、各Modelのリレーションを表現できる
each内でもfactoryを使うことでリレーションも簡潔に記述できる
staticの有無での処理速度

##static
staticって共有財産的なイメージがあるので
常にメモリの片隅に居座ってるなら、staticを使ったほうが処理速いんじゃねってイメージから試しました.

##やってみよう
```処理速度測定用クラス.java
package mk42;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;

public class StreamProcessingTest {
	private static final List<String> list = Arrays.asList("a", "s", "k");
	public static void main(String[] args) {
		Long start = System.nanoTime();
		test();
		Long end = System.nanoTime();
		Mk42.echo.accept("Processing TIme : " + (end - start) + "ns");
		/** ----------not static---------- */
		Mk42.echo.accept("next test");
		NotStaticProcessingTest no = new NotStaticProcessingTest();
		Long start2 = System.nanoTime();
		no.test2();
		Long end2 = System.nanoTime();
		Mk42.echo.accept("Processing TIme : " + (end2 - start2) + "ns");
	}
	private static void test() {
		// twice
		list.stream().forEach(v -> execute());
		list.stream().filter(v -> !v.equals("a")).forEach(v -> qwe());
		// 終端操作内部で複数処理しても、分けても、処理時間はたいして変わらない.
	}
	private static void execute() {
		List<Integer> a = new ArrayList<Integer>();
		IntStream.range(0, 10).forEach(v -> a.add(2));
	}
	private static void qwe() {
		List<Integer> a = new ArrayList<Integer>();
		IntStream.range(0, 10000000).forEach(v -> a.add(2));
	}
}

```

```staticでない実験用のメソッドまとめたクラス.java
package mk42;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;

public class NotStaticProcessingTest {
	private static final List<String> list = Arrays.asList("a", "s", "k");
	public void run() {
		System.out.println("qwe");
	}
	public void test() {
		// onece
		list.stream().forEach(v -> {
			execute();
			if(!v.equals("a"))
				qwe();
		});
		// 終端操作内部で複数処理しても、分けても、処理時間はたいして変わらない.
	}
	public void test2() {
		// twice
		list.stream().forEach(v -> execute());
		list.stream().filter(v -> !v.equals("a")).forEach(v -> qwe());
		// 終端操作内部で複数処理しても、分けても、処理時間はたいして変わらない.
	}
	private void execute() {
		List<Integer> a = new ArrayList<Integer>();
		IntStream.range(0, 10).forEach(v -> a.add(2));
	}
	private void qwe() {
		List<Integer> a = new ArrayList<Integer>();
		IntStream.range(0, 10000000).forEach(v -> a.add(2));
	}
}
```

##結果
```
static -> Processing TIme : 222787700ns
非static -> Processing TIme : 176494000ns
```
あっれー？と思いましたけど、複数回実験すると

```static.
Processing TIme : 225677500ns
Processing TIme : 223625900ns
Processing TIme : 223150400ns
Processing TIme : 228877000ns
Processing TIme : 223187400ns
```

```非static.
Processing TIme : 178923100ns
Processing TIme : 167760600ns
Processing TIme : 190593300ns
Processing TIme : 180728700ns
Processing TIme : 216358400ns
```

ちょっと平均だすのめんどくさいんでやらないですけど、そうでなく
ブレが少ないような気がしますね

staticは早いのではなく、処理速度のブレが少ないのが強みなんですかね...?
自分に必要なemacsキーバインド備忘録

# はじめに
私は普段、コーディングはVimを用い、ブラウジングではVimiumを用いています。矢印キーを押す回数が減り、便利だなぁと思っていました。

しかし、ターミナルでのコマンド履歴や編集、Vim以外の文字入力では何も考えずに矢印ポチポチしていました。そんな中、

    macの文字入力やターミナル操作ではemacsキーバインドが使える！

と言うことにようやく気づき、覚える必要ができました。

使いこなしたら絶対便利ですが、絶対忘れるので備忘録として残します。よかったら使ってください。

# キーバインド

|操作|コマンド|覚え方|
|---|---|---|
|上移動|C-p|prebious|
|下移動|C-n|next|
|左移動|C-b|back|
|右移動|C-f|forward|
|左削除|C-h||
|右削除|C-d|delete|
|行頭移動|C-a||
|行末移動|C-e||
|エンター|C-m||


上下移動はターミナルでは履歴の上下（戻る進む）に対応している。


## ブラウザでは

|操作|コマンド|
|---|---|
|URL欄へ移動|C-l|

# おわりに
macのキーボードでのdeleteは`Fn+backspace`となっていてすごく嫌だったのですが、`C-d`でできるのですね、私Macさんの事勘違いしていました(笑)

Vimは好きですが、モードという概念のため通常入力とは相性が悪いのですね。その点ではEmacsの強みがあると感じました。

    何はともあれVimと混同する・・・

メインエディタを移行しない限りは自分の混乱を避けるために最低限のコマンドだけ覚えていこうと考えています。
その前提の中で少しづつ追加していこうと思います。便利なものがあったら教えていただけると幸いです。
配列を返すメソッド-java

配列を返すメソッド（例としてint型）

```java:int[]addArray
public static int[] addArray(int x,int y) {
		int[] array = new int[2];
			array[0] = x;
			array[1] = y;
			return array;
```

addArrayメソッド内で配列を宣言する。
宣言した配列をreturnで返す。

```java:int[]addArray
			int[] array = addArray(100,200);
			for(int all:array) {
			System.out.println(all);
		}
```

arrayの出力
Ajaxで非同期パラメータ送信

#非同期でパラメータを送信（get）
```Javascript
$.ajax({
	url:"/tasks/delete/"+ deleteId,
	type:'GET',
})

//成功時の処理(resultに結果が入る)
.done( (result) => {
	//true（削除エラー）ならモーダルを出力
	if(result){
		$(".errorreveal,.errorlayer").show();
		//false（削除できた）
	}else{
	//画面をリロード
		location.reload();
	}

	//モーダルの「はい」をクリック時、モーダルを閉じる
	$(".close-errorbutton").on("click", function() {
		$('.errorreveal,.errorlayer').hide();
	});
})

//ajaxが失敗した場合の処理
.fail( (error) => {
	console.log("false");
})
```
ESXiのパスワードのポリシーを変更する

#はじめに
ESXiのrootパスワードを設定しようとした際、
デフォルトのパスワードポリシーが厳しく
意図したパスワードを設定することができなかったためメモ


#設定変更方法
ESXiのWeb GUIにログインし
ナビゲータメニューより、「管理」→「詳細設定」をクリック
「Security.PasswordQualityControl」の値を変更することでポリシーを緩めることができる


```ruby:デフォルト設定値
min=disabled,disabled,disabled,7,7
```



minのフォーマットはmin=N0,N1,N2,N3,N4であり、各項目の意味は以下の通りである。

| 項目 | 対象 | 意味 | 既定値 |
|:-----------|:------------|:------------|:------------|
| N0   | パスワード	     | 文字クラス1の場合の長さ      |disabled |
| N1   | パスワード	     | 文字クラス2の場合の長さ      |24 |
| N2   | パスフレーズ     |	全体の長さ	       |11 |
| N3   | パスワード	     | 文字クラス3の場合の長さ      |8 | 
| N4   | パスワード	     | 文字クラス4の場合の長さ      | 7| 

文字クラスとは、パスワードが何種類の文字で構成されているかを示すもので、
文字を以下の4種類に分けている。

数字
アルファベット小文字
アルファベット大文字
その他 (記号など)

そのため、`password`は文字クラス1、`P@ssword`は文字クラス2となる。

今回はアルファベット小文字のみのポスワードを設定したかったため、
以下の設定値にすることでパスワードポリシーを変更した。

```ruby:変更後
min=7,7,7,7,7
```

#補足#
本パラメータは以下の大小関係を満たす必要がある。

N0 >= N1 >= N2 >= N3 >= N4

disabledと指定された時の実際の値はINT_MAX(=環境にもよるが2147483647とか)になる。
なので、`min=disabled,6,disabled,6,6`は`min=2147483647,6,2147483647,6,6`と解釈され、
大小関係を満たせずにエラーになってしまう。

#参考にしたサイト#
http://redj.hatenablog.com/entry/2019/02/23/140222
Chrome78 の実験機能で ForceDarkMode が登場

# Chrome78 の実験機能で ForceDarkMode が登場

Chrome は以前から Experimental features を設定で試してみることができるようになっています。
将来的に実装されるかもしれない機能をひと足早く試してみることができます。

Chrome 78 では、ちょっと面白い機能がこれらに追加されました。


## Force Dark Mode for Web Contents

Chrome のアドレスバーで `chrome://flags/#enable-force-dark` を入力すると、設定項目が出てきます。
設定変更したら、 Chrome を再起動して、設定反映させます。

Chrome 73 で macOS の Dark mode 設定と連動するように、 Chrome の Dark mode が導入されましたが、これはあくまで Web contents 以外の部分に関しての見た目の変更でした。

続いて Chrome 76 では、 CSS の media query `prefers-color-scheme` に対応するようになりました。これによって、ユーザが Dark mode 設定をしているかどうかを Web site 側も判定できるようになり、それに合わせて、サイトの外観をマニュアル実装で変更できる状態になっていました。

そして、今回 Chrome 78 で Experiments として登場した機能は、 Web site 側でマニュアル実装していなくても、 Dark mode にしたときに、自動でサイトの外観を変更してしまおうという、結構アグレッシブなものです。

以下のように、結構いくつかの方式を選ぶことができます。

![chrome78_force_dark_mode_options.png](https://files.tearoom6.biz/cc750a0e-b6bc-4a49-ba1f-482437bfe180.png)

試しに、 `Enabled` に設定して、 google.com を開いてみました。う、うん...

![chrome78_force_dark_mode_google_screenshot.png](https://files.tearoom6.biz/5a2d7bbc-a24e-4e57-bd92-ac1c87855fd9.png)

きっと実際の機能としてリリースされる場合には、いい感じになっていることでしょう。


## Password Leak Detection

Chrome のアドレスバーで `chrome://flags/#password-leak-detection` を入力すると、設定項目が出てきます。
設定変更したら、 Chrome を再起動して、設定反映させます。

この機能を `Enabled` にすると、ユーザ名やパスワードの "Data breach" によって流出した、秘匿情報のデータベースとの照合が安全に行われ、もし一致した場合には、警告が表示されるとのことです。

> References

- [How to Enable Chrome 78's Hidden Dark Mode and Secure Password Features](https://lifehacker.com/1839357304)
- [How to Get Access to Experimental Features in Chrome (and on Chromebooks)](https://www.howtogeek.com/179070/how-to-get-access-to-experimental-features-on-your-chromebook-or-just-in-chrome/)
- [CSSだけでWebページをダークモード対応。ついにChromeにも対応した prefers-color-scheme が超便利｜平田 / U-NEXT｜note](https://note.mu/psephopaiktes/n/n878424784a1b)
- [How to enable password leak detection in Google Chrome • Pureinfotech](https://pureinfotech.com/enable-password-leak-detection-google-chrome/)
- [Chrome OS 78 bringing Password Leak Detection, similar to “Have I been pwned?” – About Chromebooks](https://www.aboutchromebooks.com/news/chrome-os-78-bringing-password-leak-detection-similar-to-have-i-been-pwned/)
- [What is a data breach?](https://us.norton.com/internetsecurity-privacy-data-breaches-what-you-need-to-know.html)
Fix VCTargetsPath on VC2010 cmake configure

## Error message

```
Found Windows SDK v7.1: C:\Program Files\Microsoft SDKs\Windows\v7.1\
CMake Error at CMakeLists.txt:12 (PROJECT):
  Failed to run MSBuild command:

    C:/Windows/Microsoft.NET/Framework/v4.0.30319/MSBuild.exe

  to get the value of VCTargetsPath:

    Microsoft (R) Build Engine version 4.8.3752.0

    [Microsoft .NET Framework, version 4.0.30319.42000]

    Copyright (C) Microsoft Corporation. All rights reserved.

    

    Build started 10/28/2019 9:23:08 AM.

    Project "VCTargetsPath.vcxproj" on node 1 (default targets).

    C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.Cpp.InvalidPlatform.Targets(23,7): error MSB8007: The Platform for project 'VCTargetsPath.vcxproj' is invalid.  Platform='x64'. You may be seeing this message because you are trying to build a project without a solution file, and have specified a non-default Platform that doesn't exist for this project. [VCTargetsPath.vcxproj]

    Done Building Project "VCTargetsPath.vcxproj" (default targets) -- FAILED.
```

## Cause

After installing VC2010 SP1, x64 compiler is gone.

## Fix

Install [SP1 compiler update](http://www.microsoft.com/en-us/download/details.aspx?id=4422).

> 1. Visual Studio 2010 (Express from https://visualstudio.microsoft.com/ja/dev-essentials/)
> 2. [Windows SDK 7.1](https://www.microsoft.com/en-us/download/details.aspx?id=8442)
> 3. Visual Studio 2010 SP1 (from https://visualstudio.microsoft.com/ja/dev-essentials/)
> 4. [Visual C++ 2010 SP1 Compiler Update for the Windows SDK 7.1](http://www.microsoft.com/en-us/download/details.aspx?id=4422)

## Reference

https://stackoverflow.com/a/16213408/2641271
ipa作成時に「IPA processing failed」と出た

## 概要
Xcode11、iOS13に対応したアプリのipaファイルを作成しようとすると
タイトル通り、「IPA processing failed」というエラーが出てipaファイルが作成できなかったので
調べて対処したのでメモ。

## 対処法

1. ipaファイルの作成手順通りにしていくと少し時間が立つと下の画像のような状態になってしまいます。
![ipa_error.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266735/942fd760-7133-c1ba-98ac-ccf9f377bc4c.jpeg)

2. 左下にある Show Logsからフォルダを開くと下のようなlogファイルがあると思います。そこから「IDEDistribution.standard.log」を開くことで今回のエラー内容が確認することができます。
<img width="351" alt="スクリーンショット 2019-10-24 10.59.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266735/8f60d142-343c-c1bf-09ad-8aaaf6f4bf0a.png">

3. 今回、私の場合だと、Rswiftにシュミレータアーキテクチャが含まれていたことが原因でipaファイルを作成できなかったみたいなので、[こちら](https://stackoverflow.com/questions/42641806/check-and-remove-unsupported-architecture-x86-64-i386-in-ipa-archive)を参考にアーキテクチャを削除することでipaを作成できるようになりました。（※シミュレータアーキテクチャを削除するとシミュレータでアプリ起動ができなくなるので注意が必要です。）

## まとめ
最初は原因がわからず、参考記事も見当たらずどうしようかと思いましたが、
よくよく考えればLogを見ろよって感じでした。

### 参考にした記事
- [Xcode11 で「IPA processing failed」というエラーが出たけど、無理やり ipa ファイル作成できてしまった件](https://qiita.com/90_jill/items/8a6d2e79ec5bd453b9be)
- [Check and Remove Unsupported Architecture [x86_64, i386] in IPA / Archive](https://stackoverflow.com/questions/42641806/check-and-remove-unsupported-architecture-x86-64-i386-in-ipa-archive)
- [How to fix “IPA processing failed” error in xcode 11?](https://stackoverflow.com/questions/57382217/how-to-fix-ipa-processing-failed-error-in-xcode-11)
Nuxt.jsプロジェクトでDart Sassを使う

**2020/05/03 追記
本記事は以下サイトに移転しています。**
https://kimulaco.com/post/nuxt-dart-sass/

**本記事をストックしていただいた方もいると思いますので、現時点での記事内容は残しますが、記事の更新等は移転先のみで行います。**

---

Nuxt.jsプロジェクトにDart Sassを導入した時の知見。

- Node.js v10.16.3
- Nuxt.js v2.10.2
- sass(Dart Sass) v1.23.1
- [create-nuxt-app](https://github.com/nuxt/create-nuxt-app)などでNuxt.jsプロジェクトを構築済み
- scssを使用

## Dart Sassとは

[Dart Sass](https://sass-lang.com/dart-sass)とは、Googleが開発する[Dart](https://dart.dev/)というプログラミング言語で作成された、Sassのコンパイラです。DartはJavaScriptにコンパイル可能なため、[node-sass](https://github.com/sass/node-sass)と同じようにnpm経由でインストールできます。少しわかりにくいですが、[sass](https://github.com/sass/dart-sass)というパッケージ名でnpmに公開されています。

また、Dart SassにはSassの新しい機能が先行実装される予定があったり、Node.jsのバージョン依存問題も解消できるなどのメリットがあるので、今後のSassコンパイラのスタンダードになることも考えられます。

## Nuxt.jsプロジェクトにDart Sassを導入する方法

Dart Sassを導入する前に、[create-nuxt-app](https://github.com/nuxt/create-nuxt-app)などでNuxt.jsプロジェクトを作成しましょう。

Nuxt.jsでDart Sassを使うためには[sass](https://github.com/sass/dart-sass)(Dart Sass)と[sass-loader](https://github.com/webpack-contrib/sass-loader)が必要です。さらに、コンパイル速度を向上させるために[fibers](https://github.com/laverdet/node-fibers)のインストールも推奨されているので、次のようにyarnやnpmでパッケージをインストールします。

```shell
yarn add -D sass sass-loader fibers
```

次に、nuxt.config.jsにsass-loaderの設定を追記します。node-sassの場合は特に何も設定せずに使用できましたが、Dart Sassを使用する場合は、現状追加で設定が必要なようです。

Dart Sassに関連する部分だけ抜粋すると次のようになります。

```js
// nuxt.config.js
const Sass = require('sass')
const Fiber = require('fibers')

export default {
  ...
  build: {
    loaders: {
      scss: {
        implementation: Sass,
        sassOptions: {
          fiber: Fiber
        }
      }
    }
  }
}
```

これでインストールと設定は終わりです。`.vue` ファイルにDart Sassを書くときは、node-sassと同じように、`<style>` 要素に `lang="scss"` 属性を付与するだけです。

```vue
<template>
  <p>Hello World!</p>
</template>

<script>
export default {
  name: 'HelloWorld'
}
</script>

<style lang="scss">
p { color: tomato; }
</style>
```
SE／システムエンジニアとして良い習慣を続けるためには

# 概要

前回は、SE／システムエンジニアとしての習慣でした。
今回はその２です。

[その１](https://qiita.com/fkooo/items/27d84acc09dc47083ae3 "SE／システムエンジニアとしての成功は小さな習慣の積み重ねではないか")：SE／システムエンジニアとしての成功は小さな習慣の積み重ねではないか

## 習慣を続けるには

* 必要なことには近づき、不要なことには近づかない
    * 習慣化させるために必要な機会は物理的に近づく工夫をすること。読書の習慣化するため本を持ち歩く、本を読むためのカフェを決める。
    * 逆に誘惑には物理的に近づかないようにする。つい触ってしまうアプリは敢えてショートカットを作らずアプリ一覧から起動する。など
     * 脳は一瞬見ただけで認識してしまいそれを避けるためには意思力／判断力が必要となり脳が疲弊する。そのため極力見せない工夫をする。その工夫の１案として、使ったら必ず元と位置に戻すという整理整頓が基本
* 習慣化する行動の一つ前の行動を決める
    * 早起きを習慣化するために早起き時間を決めるとともに、一つ前の行動、前の日の寝る時間を決める。
* 脳は過去のマイナスな出来事ほど記憶する。そのためプラスな出来事は意識的に記録する必要がある
    * マイナスの出来事は自然と記憶されるためそれだけで習慣化の妨げになる。逆にプラスの出来事は忘れてしまうことが多いため、毎日、日記／ノートに書いておくなど

## 参考書籍

<a target="_blank"  href="https://www.amazon.co.jp/gp/product/B07HQ41FSN/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=B07HQ41FSN&linkCode=as2&tag=se_note_001-22&linkId=3251639f3e95cb70d0ac77c994782aba"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&MarketPlace=JP&ASIN=B07HQ41FSN&ServiceVersion=20070822&ID=AsinImage&WS=1&Format=_SL110_&tag=se_note_001-22" ></a><img src="//ir-jp.amazon-adsystem.com/e/ir?t=se_note_001-22&l=am2&o=9&a=B07HQ41FSN" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
[習慣が10割](https://amzn.to/2MDv48u "習慣が10割")
【エラー対処】error failed to push some refs to pre-receive hook declinedが出るとき意外と忘れがちなこと


# はじめに

普段どおりGitKerakenでコミットして、意味もないけどプッシュしとくか〜〜
って思ったら、プッシュがいかない。

```
error failed to push some refs to pre-receive hook declined
```

みたいなメッセージが出る。

普段ならうまくいくのに、急にいかない！？ってなりました。

# 色々探した後...

色々とネットを探しても、関係ありそうな情報がない。
そこで、ファイルを入れたり出したりを繰り返すとどうやら重いファイルを含んでいると上記エラーが出ているっぽい。

GitHubの制約を見ると

- 50MB以上のファイルで警告が出る
- 100MB以上のファイルはアップロードできない

とありました。

どうやらGitKerakenではこのように100MB以上のファイルを含んでいるとエラーを

```
error failed to push some refs to pre-receive hook declined
```

のように出すっぽいです。

事実、100MB以上のファイルを除けば普通にプッシュできました。
Google Apps Scriptを用いてスプレッドシート上のカスタム関数をリフレッシュする

# 背景と概要
スプレッドシートのセルへ配置したカスタム関数をリフレッシュ（再計算）させようとすると、カスタム関数を一度削除して再度設置する、カスタム関数のスクリプトをスクリプトエディタ上で保存する、あるいは[カスタム関数へ与えている引数の値を変化させる](https://gist.github.com/tanaikech/b8ea7bd7fd87bcd7bb28ddede1781889)などの処理が必要です。ここでは、2019年4月5日に追加されたClass TextFinderを使って少しシンプルな方法を紹介させていただきます。この場合、カスタム関数だけでなくbuilt-in関数もリフレッシュできます。

# 原理
これまでの経験で、カスタム関数は、一度削除して再度配置することでリフレッシュできることが分かっています。これをClass TextFinderで実現します。具体的には、カスタム関数の一部分、例えば`=`を一度別の文字に置き換えてから再度元に戻すことでカスタム関数をリフレッシュさせます。

# サンプルスクリプト
## パターン 1
このパターンでは、スプレッドシート内の全てのシートの全てのカスタム関数、built-in関数がリフレッシュされます。

```javascript
function myFunction() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var temp = Utilities.getUuid();
  ss.createTextFinder("=").matchFormulaText(true).replaceAllWith(temp);
  ss.createTextFinder(temp).matchFormulaText(true).replaceAllWith("=");
}
```

また、TextFinderはシンプルトリガーでも実行可能です。これを利用することで、例えばスプレッドシートを開いた際にカスタム関数をリフレッシュすることも可能です。実は、Sheets APIのFindReplaceでも同様のことは可能なのですが、この場合、シンプルトリガーでは実行できなかったり、Advanced Google servicesでSheets APIを有効にする必要があるという点で少し面倒を感じていましたが、TextFinderが追加されたことでこれらが解消されました。このためのサンプルスクリプトは下記の通りです。これを実行するには、スクリプトをコピーペーストして保存し、スプレッドシートを一度閉じてから再度開きます。これにより`onOpen`が実行されます。

```javascript
function onOpen(e) {
  var temp = Utilities.getUuid();
  e.source.createTextFinder("=").matchFormulaText(true).replaceAllWith(temp);
  e.source.createTextFinder(temp).matchFormulaText(true).replaceAllWith("=");
}
```

## パターン 2
このパターンでは、特定のカスタム関数のみをリフレッシュします。このためのサンプルスクリプトは下記の通りです。

```javascript
function myFunction() {
  var customFunctions = ["CUSTOM1", "CUSTOM2"]; // ここにリフレッシュしたいカスタム関数名をセットします。

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var temp = Utilities.getUuid();
  customFunctions.forEach(function(e) {
    ss.createTextFinder("=" + e).matchFormulaText(true).replaceAllWith(temp);
    ss.createTextFinder(temp).matchFormulaText(true).replaceAllWith("=" + e);
  });
}
```

## 追記
- TextFinderは特定のrangeやシート内での検索も可能です。上記のサンプルはスプレッドシート内の全てのシートで実行されますが、これを制限することも可能です。

## 参考
- [Custom Functions in Google Sheets](https://developers.google.com/apps-script/guides/sheets/functions)
- [Class TextFinder](https://developers.google.com/apps-script/reference/spreadsheet/text-finder)
- [Automatic Recalculation of Custom Function on Spreadsheet Part 1](https://gist.github.com/tanaikech/b8ea7bd7fd87bcd7bb28ddede1781889)
- [Automatic Recalculation of Custom Function on Spreadsheet Part 2](https://gist.github.com/tanaikech/cb5447616bfc6a01de8a49131c0d2db0)
【遭難防止】Git初心者のための現状確認コマンドの意味まとめ git status, git log,git diff【俺、今どこにいるの？】

これを理解するまで、例えるなら山で地図とコンパスとGPSを持っているけど使い方がわからなくて（使っていなくて）道迷いしまくるような状態でした。

**「もうGitで遭難したくない！」**というあなたに役立てばと思います。

誤り等あればご指摘頂けますと幸いです。

## この記事が役立つ人
- 細かい表示内容は置いといて、**意味**を知りたい
- 確認系の各種コマンドはよく分からない
- Git初心者
- `add` `commit` `push`の意味は分かる



## 各コマンドの表示単位
表示単位が小さい順から大きい順です。

### 【小】git diff
**「ファイルの中身」**を表示。

差分を抽出してくれる。
`q`で抜けられる。

### 【中】git status
**「ファイル」**を表示。

現在、最新の`commit`後にどこが変更になったのかをファイル単位で教えてくれる。

### 【大】git log
**「`commit`」**を表示。

現在いる`branch`の中での「`commit`の履歴」を教えてくれる。

## 表示したいこと別　コマンド一覧
オプションも多すぎて、どれを使ったらいいか分からないですよね。
これを使えば現状把握にはそう困らないと思います。

まずはオプションなしで使ってみることで、根本の機能を理解するのが大事ですね。

※**注意点**
あれ？戻らない！と思ったら、だいたい`q`を押せば抜けられます。

### 【ファイルの中身単位】git diff

1.（オプションなし） `add`される前の内容を表示したい。
	 
```zsh
$ git diff
```

2.`add`されてるけど`commit`されていない内容を表示したい。

```zsh
$ git diff --cached
```

### 【ファイル単位】git status
1.（オプションなし）前回の`commit`から変更のあったファイルを表示したい。

```zsh
$ git status
```
2.コンパクトに`git status`を表示したい。

```zsh
$ git status -s
```

### 【commit単位】git log
1.（オプションなし）`commit`した履歴を一覧表示したい。

```zsh
git log
```
2.コンパクトに`git log`を表示したい。

```zsh
git log --oneLine
```
3.どこを変更したかを`git log`を表示したい。
	追加表示されるのは**「ファイルの中身」**。
	`git diff`をついでに表示するイメージ。

```zsh
git log -p
```
4.どこを変更したかを`git log`を表示したい。
	追加表示されるのは**「行数」**。
	追加・削除件数が視覚的に分かるので「ここに大きな変更があったんだ」とわかりやすい。

```zsh
git log --stat
```

## 参考にさせて頂いたサイト（いつもありがとうございます）
[git入門 (全22回) - プログラミングならドットインストール](https://dotinstall.com/lessons/basic_git)
[git logコマンドまとめ - Qiita](https://qiita.com/ma5aki-Y/items/2f5d57207bbd8a57b15e)
PreferenceManagerが@Deprecatedで困った話

AndroidStudioで何も考えずにPreferenceManagerを使っていると以下のようなアラートが発生してちょっと困りました。

<img width="672" alt="スクリーンショット 2019-10-28 8.09.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363095/5fd45388-ff0f-fbb9-a9d7-938371054aba.png">

[APIレベル29で廃止されたからあんまり使わないでね](https://developer.android.com/reference/android/preference/PreferenceManager)ってことらしいです。
そのうち使えなくなるよーとのこと。
まあ、当分は使えるみたいですけど。
AndroidX Preference Library　を使えとのことです。
以下、AndroidX Preference Libraryの使いかた。

##build.gradleに追加
build.gradle(appの方)のdependenciesに
implementation 'androidx.preference:preference:1.0.0'を追加すればOK。

```build.gradle
dependencies {
    implementation 'androidx.preference:preference:1.0.0'
}
```
変更したら、忘れずにSyncしましょう！！

##import先の変更
import android.preference.PreferenceManagerに
ただ「x」を追加するだけ。以上。

```○○○.kt
- import android.preference.PreferenceManager
+ import androidx.preference.PreferenceManager
```


参考：
https://maku77.github.io/android/fw/preference-fw.html
(初心者向け)S3とそのアクセス管理の方法まとめ

###はじめに
AWSの基本サービスのS3ですが、アクセス管理がややこしいので整理するために書きました。ざっくりです。間違ってたら教えてください。

##S3とは
*Simple Storage Service*
AWSのストレージサービス。容量無制限（従量課金）で安価、障害時の耐久性に優れている。データの保存・バックアップの用途のほか、静的ファイルをアップロードしてWebページとして公開することもできる。

###用語
オブジェクト・・・S3に保存するファイル
バケット・・・オブジェクトの置き場所。フォルダみたいなもの。
キー・・・オブジェクトを指定するための一意の文字列。（オブジェクトの名前）

##S3でのアクセス管理
デフォルトでは全てプライベート（バケット、オブジェクトを作成したAWSアカウントのみがアクセスできる）。
アクセスポリシーによって許可・拒否を定義する。


###アクセス許可の流れ
S3はリクエストを受け取るとアクセス権があるかどうかのアクセスポリシーを確認し、許可するかを決める。

アクセスポリシーの種類は以下
・ユーザーポリシー
・バケットポリシー
・ACL
　・バケットACL
　・オブジェクトACL

###ユーザーポリシー
=IAMでのアクセス管理
「このユーザーは何ができるか」を定義する。

###バケットポリシー
「このバケットには誰がアクセスできるか」を定義する。
IPアドレスでの制限やMFA(多要素認証)制限、CloudFrontからのアクセスのみ許可する・・・など。
###ACL
アクセスコントロールリスト
ユーザーポリシー、バケットポリシーより優先順位は低い。通常はユーザーポリシー、バケットポリシーで制御し、さらに細かい制御が必要な場合にACLを用いる。

####バケットACL
バケットACLに関しては公式に以下の記述があります。
> バケット ACL の使用が推奨される唯一のケースは、Amazon S3 のログ配信グループに、バケットへのアクセスログオブジェクトの書き込みアクセス許可を付与する場合です。

[アクセスポリシーのオプションを使用するためのガイドライン](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/access-policy-alternatives-guidelines.html) より

####オブジェクトACL
バケットポリシー、バケットACLがバケット単位であるのに対し、オブジェクトACLはオブジェクト単位でのアクセス管理。特定のオブジェクトに対しての制御が必要な場合に用いる。
バケット所有者が他のAWSアカウントにオブジェクトのアップロードを許可する場合は、オブジェクトACLでアクセス許可する必要がある。

###その他
他に、ブロックパブリックアクセス設定というものもあり、リソースへのパブリックアクセス(公開)を制限できる。

###参考
[Amazon S3とは](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/Welcome.html)
[Amazon S3 リソースへのアクセス許可の管理の概要](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/intro-managing-access-s3-resources.html)
[20190220 AWS Black Belt Online Seminar Amazon S3 / Glacier](https://www.slideshare.net/AmazonWebServicesJapan/20190220-aws-black-belt-online-seminar-amazon-s3-glacier)


###さいごに
アクセス管理の細かい制御や関係については公式や他に良い記事がたくさんあるのでそちらを見ていただければと思います。
以上、どなたかのお役に立てば幸いです。
Pythonの正規表現で特殊記号をすべて闇に葬り去りたいとき


# 記号がいらない

/ * # %
など、スクレイピング・自然言語処理においては記号はいらない場合があります。

Pythonのreモジュールで一括削除をします。

```py
import re
code_regex = re.compile('[!"#$%&\'\\\\()*+,-./:;<=>?@[\\]^_`{|}~「」〔〕“”〈〉『』【】＆＊・（）＄＃＠。、？！｀＋￥％]')

txt = input().rstrip()
cleaned_text = code_regex.sub('', txt)
print(cleaned_text)
```

`[]`に入っている記号のどれかに一致してしたとき削除してくれるため、この中にいらない文字を入れて削除をします。
全角の記号も強引に打ち込んで闇に葬り去りましょう。