OmniAICreator/Qiita-1.07M huggingface dataset:
Quantum ESPRESSO入力ファイル作成手順１１．LDA+U

クロスアビリティ Winmostarサポートチームです。
WinmostarはQuautum ESPRESSOを簡単かつ高度に利用するための統合GUI環境となっています。学生は無料で利用でき、学生以外も無料トライアルを入手することができますので、是非 [WinmostarのWebサイト](https://winmostar.com/jp/) をご覧ください。

#0. はじめに
第一原理計算ソフトQuantunm ESPRESSO <https://www.quantum-espresso.org> の入力ファイルの書き方について、複数回にわたって解説していきます。今回は第１１回目です。LDA+Uの使い方を解説します。

> この記事では、初歩的な内容しか紹介しません。
> 入力ファイルの詳細について知りたい方は、マニュアル http://www.quantum-espresso.org/Doc/INPUT_PW.html をご参照下さい。


#1. LDAおよびGGA
Kohn-Shamの密度汎関数理論では、基底状態エネルギーを再現可能な交換相関汎関数が存在することを仮定している。当該汎関数が存在することは未だ証明されておらず、且つ、存在した場合にそれが多項式オーダー(P=PN)で演算可能であるかは不明である。そこで、交換相関汎関数には、多項式オーダーで演算可能な近似手法を適用する。現在最もよく使われる近似手法が、LDAおよびGGAである。LDAでは、指定された座標における交換相関エネルギー密度を該当座標における電子密度のみで決定する手法である。GGAでは、電子密度およびその勾配を使用する。いずれも計算コストが低く、多くの系に適用されている。しかしながら、近似手法であるが故に、いくつかの種類の誤差を含んでいる。最も大きな誤差が、自己相互作用誤差と呼ばれるものでる。自己相互作用誤差は、電子を過剰に非局在化させる性質がある。元来LDAおよびGGAは金属中の自由電子を再現するように設計されており、局在化した電子状態の表現に適さないのである。遷移金属酸化物におけるdまたはf軌道の電子は特に局在化が強いことが知られており、このような系においてはLDAおよびGGAは定性的にさえ誤った結果をもたらす。そこで考案された補正方法が、LDA+U（またはGGA+U）と呼ばれるものである。遷移金属のdまたはf軌道に対して、電子が局在化するように外部ポテンシャルを加算するのである。当該のポテンシャルの大きさは、”U”という変数で記される。


#2. LDA+U
Quantum ESPRESSOにてLDA+Uを利用する場合、入力ファイルにて以下の設定をします。

```
&SYSTEM
  lda_plus_u   = .TRUE.
  hubbard_u(1) = 5.0
  hubbard_u(2) = 3.0
  hubbard_u(3) = 0.0
/
```

lda_plus_u を.TRUE.に設定すると、LDA+Uが適用されます。hubbard_u にて元素ごとに、Uの値を設定します。単位は、eVです。  hubbard_u が 0 の元素については、LDA+Uが適用対象外となります。

Uの値は一意的には決まらず、系に応じて適時選定する必要があります。一般的には、3.0～5.0eV 程度を設定するのが通例です。既報の文献値があれば、それを参考とするのが良いです。また、Materials Project <https://www.materialsproject.org> でも多くの遷移金属酸化物について、U値が公開されていますので、これも参考になります。Materials ProjectのWebでは、個々の化合物のページの「Calculation Summary」に「U Values」として書かれています。

---------------------------------------
なお、Winmostarを利用するとQuautum ESPRESSOをGUI上から簡単かつ高度に活用することができます。学生は無料で利用でき、学生以外も無料トライアルを入手することができますので、是非 [WinmostarのWebサイト](https://winmostar.com/jp/) をご覧ください。

Quantum ESPRESSO入力ファイル作成手順シリーズ
[１．結晶構造の作成](https://qiita.com/xa_member/items/727c1a62930611babaf7) 
[２．SCF計算の設定](https://qiita.com/xa_member/items/a098e94d633a1d29f1c0) 
[３．擬ポテンシャルファイルの選択方法](https://qiita.com/xa_member/items/006d9dd44c662a17903d) 
[４．原子座標のみの最適化](https://qiita.com/xa_member/items/dc860b1656f7dfe93c8a)
[５．格子ベクトル及び格子内部の原子座標の最適化](https://qiita.com/xa_member/items/4c667817e50facd8a770)
[６．状態密度の計算](https://qiita.com/xa_member/items/7aa75304b2ce7f90c8d4)
[７．局所状態密度の計算](https://qiita.com/xa_member/items/95c7bd64981f7329b94b)
[８．バンド構造の計算](https://qiita.com/xa_member/items/a519c53b63df75a68894)
[９．バンド数の設定](https://qiita.com/xa_member/items/d923ea537328cdba8b10)
[１０．van der Waals相互作用](https://qiita.com/xa_member/items/bd64362329c7235bf248)
[１１．LDA+U法](https://qiita.com/xa_member/items/ab3e1333e92bc424f5a7)
[１２．NEB法](https://qiita.com/xa_member/items/e3b63a1fdca12f95e8cb)
[１３．Phonon計算（特定q点）](https://qiita.com/xa_member/items/77e464c01c5db1e847ea)
[１４．Phonon計算（バンド構造）](https://qiita.com/xa_member/items/5c02fcae08431588659d)
[１５．擬ポテンシャルの作成](https://qiita.com/xa_member/items/5feb8f432170141c89cd)
[１６．擬ポテンシャルのテスト](https://qiita.com/xa_member/items/3902c1660fb7064a4c34)
[１７．SCF計算の入力ファイルの実例](https://qiita.com/xa_member/items/febde40c8a17b7b83cc5)
ColaboratoryでOpenAIGymを動作させる

#はじめに

いくつかのサイトでみると、以下のコード実行で仮想のディスプレイを割り当てると、
動作させることができるとのことですが、現在（2019/08/05）時点ではうまくいかないようです。
「display.start()」を実行する箇所で
「xdpyinfo was not found, X start can not be checked! Please install xdpyinfo!」
のエラーが表示されます。

```Python
!apt-get -qq -y install libcusparse8.0 libnvrtc8.0 libnvtoolsext1 > /dev/null
!ln -snf /usr/lib/x86_64-linux-gnu/libnvrtc-builtins.so.8.0 /usr/lib/x86_64-linux-gnu/libnvrtc-builtins.so

!apt-get -qq -y install xvfb freeglut3-dev ffmpeg> /dev/null
!pip install pyglet
!pip install pyopengl
!pip install pyvirtualdisplay
!pip install gym[classic_control]

from pyvirtualdisplay import Display
display = Display(visible=0, size=(1024, 768))
display.start()
import os
os.environ["DISPLAY"] = ":" + str(display.display) + "." + str(display.screen)
```

#対応方法（2019/08/05時点）

xdpyinfoとその関連ファイルが無いので以下の３つをUbuntu18.04環境からコピーする。
xdpyinfoには実行権限を付ける。

/usr/bin/xdpyinfo
/usr/lib/x86_64-linux-gnu/libXxf86dga.so.1
/usr/lib/x86_64-linux-gnu/libXxf86dga.so.1.0.0

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93459/4dee2feb-da26-e64a-8e70-0da9fa300d02.png)

ファイルをアップロードしてから以下コマンドを実行する。

```
!cp xdpyinfo /usr/bin/
!cp libXxf86dga.* /usr/lib/x86_64-linux-gnu/
!chmod +x /usr/bin/xdpyinfo
```

エラーにならずに実行できるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93459/c4c900b3-6dc5-608f-4eb0-74fc9b064bd8.png)

（2019/08/26追加）
gymの環境作成時に「wrappers.Monitor()」を使うことで、mp4ファイルに出力できる。
上記の方法での仮想ディスプレイの割り当てを行わなくても良いようです。
動画も出力できるので、こちらを使った方がよさそうです。

```Python
  from gym import wrappers
  ENV_NAME = 'MsPacman-v0'
  env = gym.make(ENV_NAME)
  env = wrappers.Monitor(env, '/content/drive/My Drive/movie_folder', video_callable=(lambda ep: ep % 100 == 0))

```

#対応方法（2020/01/07時点）
pygletおよびtensorflowのバージョンを下げたりしないと上記のやりかたでは動かないようです。
現在時点で以下の方法で実行できるようです。

①以下３ファイルのアップロード
xdpyinfo
libXxf86dga.so.1
libXxf86dga.so.1.0.0

②以下コマンドでファイル配置およびパッケージのインストール

```
!cp xdpyinfo /usr/bin/
!cp libXxf86dga.* /usr/lib/x86_64-linux-gnu/
!chmod +x /usr/bin/xdpyinfo

!pip uninstall pyglet -y
!pip install pyglet==1.2.4
!pip install keras-rl gym
!pip install tensorflow==1.13.1

!apt-get -qq -y install libcusparse8.0 libnvrtc8.0 libnvtoolsext1 > /dev/null
!ln -snf /usr/lib/x86_64-linux-gnu/libnvrtc-builtins.so.8.0 /usr/lib/x86_64-linux-gnu/libnvrtc-builtins.so

!apt-get -qq -y install xvfb freeglut3-dev ffmpeg> /dev/null
!pip install pyopengl
!pip install pyvirtualdisplay
!pip install gym[classic_control]
```

③「ランタイム」→「ランタイムを再起動」

④以下のコード実行で仮想ディスプレイを有効にする

```Python
from pyvirtualdisplay import Display
display = Display(visible=0, size=(1024, 768))
display.start()
```

⑤あとは環境作成時にwrappers.Monitor()を使えばよいようです。

```Python
from gym import wrappers
env = gym.make(ENV_NAME)
env = wrappers.Monitor(env, '/content', video_callable=(lambda ep: ep % 100 == 0))
```
Rails 3-5 複数のデータベースに接続する方法

Rails 6 からは複数データベースが標準でサポートされた形になります(専用の書き方が決まっています)。
Rails 3-5 では次のようにすると、複数データベースを扱えます。

## Config

データベースの設定をまず書きます。
基本的に `database.yml` に書けばOKで、 どんな名前でもOKです。

環境ごとの複数データベースを使うには、下のように複数のデータベースを記述します。

```yaml:config/database.yml

development:
  ...

development_sub:
  ...

production:
  ...

production_sub:
  ...
```

## 抽象クラス作成

抽象クラスを作成して、追加されたデータベースを使う場合の基底クラスを作成します。

通常 Rails のモデルは ApplicationRecord を継承して "development" や "production" として設定されたデータベースを使うことになります。
作成する抽象クラスでは、 `Rails.env` に応じて接続先のデータベースを決定するようにします。


```ruby:SubBase
class SubBase < ApplicationRecord
  self.abstract_class = true

  environment = Rails.env + "_sub"
  establish_connection(environment.to_sym)
end
```

## 使い方

ApplicationRecord を継承して従来通りのモデルの作り方をすると、 "development" や "production" に記述したデータベースを使用できます。
SubBase を継承してモデルを作成すると、 "development_sub", "production_sub" に記述したデータベースを使用できます。
AtCoder Beginner Contest 136 D - Gathering Children

本番中はくだらないミスで正解できなかった。


https://atcoder.jp/contests/abc136/tasks/abc136_d

少し試行を繰り返すと、RLのポイントで子供の数が2回ごとにぐるぐる入れ替わることがわかる。
LかRのポイントを連続してふむ子供がいるうちはその子供はずっと移動し続けるが、どんなに長くとも石版の長さの分の時間が経過したら全ての子供がどこかのRLポイントでぐるぐるしているはずだ。

だから、まず石版の長さの分(k回とする)試行を繰り返し、地点ごとの子供の数をカウントする。
その後、rとlが連続しているポイントをすべて取得。
10**100は偶数なので、kが偶数なら残りの試行回数も偶数、kが奇数なら奇数。
子供の人数は2回の周期で変わるので、kが偶数ならそのまま。奇数ならRLで入れ替える。


```python
li=input().split()[0]
child_li=[1]*len(li)
for i in range(len(li)):
    new_child_li=[0]*len(li)
    for j in range(len(li)):
# jでそれぞれのますをみる
        if li[j]=='R':
            new_child_li[j+1]+=child_li[j]
        else:
            new_child_li[j-1]+=child_li[j]
    child_li=new_child_li


rl_list=[(i,i+1) for i in range(len(li)-1) if li[i]=='R' and li[i+1]=='L']

        
if len(li)%2:
    for i in rl_list:
        new_child_li[i], new_child_li[i+1]=new_child_li[i+1], new_child_li[i]
print(*new_child_li, sep=' ')

```
追記：この解法は時間制限で無理でした。
この解法だと計算量は$O(N^2)$で、$N=10^5$だと無理だということが判明しました。pythonの限界は
$O(10^6)$くらいのようです。

# 改良版
RとLのそれぞれについて、RL文字列を走査して、同じ文字が連続する数を数える。まずRについて考える。

Rについては左から走査して、Lがくるまで連続するRをカウントする。十分に多い回数の試行をしたらこの初めて出現したLとその直前のRのどちらかにこれまでの連続したRにいた子供たちは割り振られるとわかる。
偶数回(10**100は偶数)試行したら、今見ているRLの前にあった連続したRについて、0始まりのindexで偶数番目のRにいた子供はRLのR側に、奇数番目のRにいた子はL側にいるとわかる。これでRにいる子供たちについては終わった。

Lに関しても同様の要領でやる。ただし今回は右からLR文字列を走査して、連続したLの数を左側のRLのいずれかに割り振ります。

これを足し合わせることで答えが出る。実際には$O(N)$でとける問題だった。

```python
li=input()
n=len(li)
child_li=[0]*n



ruiseki=0
for i in range(n-1):
    if li[i]=='R':
        ruiseki+=1
        if li[i+1]=='L':
            child_li[i+1]=ruiseki//2
            child_li[i]=(ruiseki+1)//2
    else:
        ruiseki=0

        
ruiseki=0
for i in range(n-1, 0, -1):
    if li[i]=='L':
        ruiseki+=1
        if li[i-1]=='R':
            child_li[i-1]+=ruiseki//2
            child_li[i]+=(ruiseki+1)//2
    else:
        ruiseki=0
        
print(*child_li)

```
Ubuntu18にApache Sparkのインストール。2019-08-05

# 概要
2019年8月時点の [Apache Spark](https://spark.apache.org/) のインストールメモです。（自分の作業メモです）
とりあえずなんか動いた！というのを確認するところまでやります。

# 環境

```
% cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.2 LTS"
```

# 準備

Javaのインストール

```
% sudo apt-get install openjdk-11-jdk
% java --version
openjdk 11.0.4 2019-07-16
OpenJDK Runtime Environment (build 11.0.4+11-post-Ubuntu-1ubuntu218.04.3)
OpenJDK 64-Bit Server VM (build 11.0.4+11-post-Ubuntu-1ubuntu218.04.3, mixed mode, sharing)
```

# Apache Sparkのインストール

https://spark.apache.org/downloads.html
ダウンロードして展開して終了です。

```
% wget https://www.apache.org/dyn/closer.lua/spark/spark-2.4.3/spark-2.4.3-bin-hadoop2.7.tgz
% tar -xzf spark-2.4.3-bin-hadoop2.7.tgz
```

とりあえずダウンロードして展開したそのままで進めます。
ちゃんとやるなら `/usr/local` とか `/opt` の下あたりに配置しつつ環境変数も各シェルのrcあたりに書いておくと良いです。

```
% cd spark-2.4.3-bin-hadoop2.7
% export SPARK_HOME=$(pwd)
% export PATH=$PATH:$SPARK_HOME/bin
```

# とりあえず動かしてみる

`spark-shell` を起動してみる

```
% spark-shell
（...Warningとか出たけどとりあえず気にしないことにする）
Spark context Web UI available at http://10.0.2.15:4040
Spark context available as 'sc' (master = local[*], app id = local-1564991419374).
Spark session available as 'spark'.
Welcome to
      ____              __
     / __/__  ___ _____/ /__
    _\ \/ _ \/ _ `/ __/  '_/
   /___/ .__/\_,_/_/ /_/\_\   version 2.4.3
      /_/

Using Scala version 2.11.12 (OpenJDK 64-Bit Server VM, Java 11.0.4)
Type in expressions to have them evaluated.
Type :help for more information.

scala>
```

とインタラクティブシェルが起動すれば大丈夫でしょう。
とりあえず動いた！というのが確認できました。

# まとめ

自分の作業メモがてら2019年8月時点のApache Sparkのインストールについて書きました。

（Apache Sparkのインストールについてここ数年くらいで大きな変更はなさそうな雰囲気、だったのでわざわざ書かなくてよかったかも :cry: ）
「Failed to transform file 'kotlin-compiler-embeddable-1.2.71.jar' to match attributes {artifactType=processed-jar} using transform JetifyTransform」と出てビルドがこける

# エラーログ

AndroidX対応をして、circleciでビルドしたところこんな感じのエラーが出ていました。

```
* What went wrong:
Execution failed for task ':modules:legacy:kaptGenerateStubsDevDebugKotlin'.
> Could not resolve all files for configuration ':modules:legacy:kapt'.
   > Failed to transform file 'kotlin-compiler-embeddable-1.2.71.jar' to match attributes {artifactType=processed-jar} using transform JetifyTransform
      > Failed to transform '/home/circleci/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-compiler-embeddable/1.2.71/a79f934bfbc1c7e16638da3474feab351735f1c0/kotlin-compiler-embeddable-1.2.71.jar' using Jetifier. Reason: Malformed input or input contains unmappable characters: javaslang/?.class. (Run with --stacktrace for more details.)
```

# 調査した結果

とりあえずググってみたところ、こちらの記事がヒットしました。

https://github.com/square/moshi/issues/804

# 解決法

gradle-propertiesファイルにこのようにjetifierのブラックリストに追加する。

```gradle:gradle-properties
android.jetifier.blacklist = kotlin-compiler-embeddable-.*\\.jar
```

ただ、今の所警告が出るっぽい。。良いやり方知っている方いれば教えてください。

```
WARNING: The option setting 'android.jetifier.blacklist=kotlin-compiler-embeddable-.*\.jar' is experimental and unsupported.
```
Azure IoT Centralで受信しているJSON形式を確認する方法

#やりたいこと
Azure IoT Centralで受信するデータ形式(JSON形式)を確認したい

#なぜ確認したいのか？
* FA関連ツールからJSON形式でデータを送信してみたが、Azure IoT Centralで正しく受信できていない
* ツールの機能を使っているが、実際にどういった形式で送信しているのかが分からない
* Azureポータルの画面上では、どういったデータを受信しているかが分からない
* つまり、なんで正確に受信できないかのデバッグがすごく大変だった

#解決策
Microsoft公式で紹介されている方法で、Azure IoT Centralが受信しているデータ形式が確認できます。
残念ながら、Azureポータルの画面上から確認できないので、その点は注意。
https://docs.microsoft.com/en-us/azure/iot-central/howto-use-iotc-explorer

#今後の要望
####FA関連ツール側
* 送信できるJSON形式をカスタムできるようにして欲しい

####AzureIoTCentral側
* 受信できるJSON形式をカスタムできるようにして欲しい
* Azureポータルの画面上で受信しているJSON形式を確認できるようにして欲しい

#注意事項
* proxyがあるとツールが動作しないので、その辺りは注意

#今回問題になった実際のJSON形式
どちらもありだと思うのですが、この辺りがまだまだ過渡期って感じでしょうか。
####FA関連ツールが出力するJSON形式
```
 {
    id: "aaa",
    v: 111
  }, 
  {
    id: "bbb",
    v: 222
  }
```

####AzureIoTCentralが期待するJSON形式
```
{
  aaa: 111,
  bbb: 222
}
```
GoogleChromeのおすすめ拡張機能

私がGoogleChromeに入れていて、長らく削除していない保存版の拡張機能を紹介します。

#### [Vimium - Chrome ウェブストア](https://chrome.google.com/webstore/detail/vimium/dbepggeogbaibhgnhhndojpepiihcmeb)

これはハイパー便利！！vimを使う感覚で、マウスを使わずにChromeを自由自在に操れる感じ♪

#### 	[Clear Cache - Chrome ウェブストア](https://chrome.google.com/webstore/detail/clear-cache/cppjkneekbjaeellbfkmgnhonkkjfpdn)

ワンクリックでキャッシュをクリアします。
オプション*Automatically reload active tab after clearing data*を有効にすることで、ワンクリックでキャッシュをクリア後、リロードまで自動で行ってくれます。

#### [Web Server for Chrome - Chrome ウェブストア](https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb)

ローカルにApacheなどを入れないでもlicalhostを手軽に使えます。
※PHPなどは使えません。

####  [LINE - Chrome ウェブストア](https://chrome.google.com/webstore/detail/line/ophjlpahpchlmihnnnihgmmeilfjmjjc)

LinuxだとLINEアプリを入れられないので、これを使ってPCからLINEをしています。
※WindowsやMacでLINEをする場合はLINEアプリを入れた方が使いやすいと思います。

#### その他

永久保存版！という拡張機能を発掘したら都度追記します。
biopythonでHMMERの結果をparseする

# まずはHMMERで検索
`hmmscan -o out_hmmscan.txt --cpu 4 -E 1e-10 prof.hmm some_proteins.fa`

# 検索結果をparse

```python:parse_hmmscan.py
#!/usr/bin/env python3

from Bio import SearchIO

qres=SearchIO.parse('out_hmmscan.txt', 'hmmer3-text') 

for q in qres:
    if len(q) >= 1:
        for hit in q:
            print('*** HIT ***')
            print(q.id)
            print(hit.id)
            print(hit.evalue)
            print()
            for hsp in hit:
                print(hsp.query.seq)
                print(str(hsp.aln_annotation['PP']))
                print(hsp.hit.seq)
                print()
            print()

```

# 環境
Ubuntu 18.04
hmmer 3.1b2
Python 3.7.2
biopython 1.72
jqueryの.offset()メソッドで対象の要素が存在しない場合エラーになる

位置取得の処理で、例えば

```javascript:hoge.js
$('.hoge').offset().top
```
という処理を書いて、その$('.hoge')の要素が存在しない場合エラーになります。

```javascript:hoge.js
if ($('.hoge').length){
    $('.hoge').offset().top
}
```
などで、対象の要素が無かった場合処理をしないif文で対応しましょう。
.lengthプロパティで.hogeが無かった場合は0になるので、処理されません。
iOSの証明書を作る

# なんでいまさら？
iOSのアプリ開発を初期のころからやっていたので、たまにしか行わない証明書の作成は、キーチェーンを起ち上げて、証明書アシスタントからファイル作って、developer.apple.comにアップして・・・というめんどくさい方法を取ってました。

でもつい最近気がついたんですよね。

Xcodeから作成できるようになっていたことを😅
いつのころからなのかは知らない・・・。結構前なのかな。恥ずかしい😩

こんな人おそらくいないと思いますが、自分みたいに周回遅れになっている人もいるかと思い、記録として残しておきます。

# 作成方法

1. Xcodeを起動して、`Preferences...` を開く

2. Accountsを選択し、`Manage Certificates...` をクリック

<img width="912" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656/9c8cf078-6a45-194c-6e3f-55fd4d807e85.png">

3. 証明書の一覧がでるので、削除するなら選択して右クリックで削除できる。
4. 証明書を追加する場合は、左下の`+`ボタンをクリックする

<img width="912" alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656/41714695-d155-44f6-b5d9-73395594cf62.png">

5. `Apple Devlelopment`か`Apple Distrubution`を選ぶだけ

<img width="237" alt="3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656/0f19493b-b912-a219-1598-75bd6b3e5a71.png">

これでdeveloper.apple.comの方に登録されます。  
ただ欠点があって、証明書の名前を決められないんです。

それでもDevelopmentの証明書なら問題ないのではないでしょうか。
Docker for MacでNameVirtualHostを使った開発環境を楽に作る方法

Apache1台でNameVirtualHostでローカルドメインで振り分けるタイプのプロジェクトが多々ありますが、Hostファイルの書き換えに使っていた[Hoster](http://www.redwinder.com/macapp/hoster/)がMojaveアップデート後いよいよ使えなくなりました。

## 目的

- /etc/hostsの書き換えはやりたくない
- できればワイルドカードで指定したい(*.testなど）

## まとめ

- hostsファイル書き換えからの乗り換えであれば、ローカル用のDNSを導入する
- Webのみで良ければnginx-proxyを使う

## パターン1 ローカル環境のDNSサーバーを使う

DNSサーバーをローカルに作ります。*dnsmasq*が軽量で入れやすいのでこちらを使います。

※ 最初*.devを設定していましたが、devドメインはChrome環境でhttpsにリダイレクトする仕様になっているので、*.testドメインに変更しました。

https://qiita.com/lara_bell/items/f7f3c5189530090229ed

### dnsmasqのインストール

brew経由で*dnsmasq*をインストールします。

```
$ brew install dnsmasq
```

dnsmasqの自動起動設定を行います。

```
$ sudo brew services start dnsmasq
```

### *.testを -> 127.0.0.1 に向ける設定

```
$ echo 'address=/.test/127.0.0.1' > /usr/local/etc/dnsmasq.conf
```

### *.testのネームサーバーをdnsmasqに指定

```
$ sudo mkdir -v /etc/resolver
$ echo "nameserver 127.0.0.1" | sudo tee -a /etc/resolver/test
```

### 試してみる

```
$ ping hogehoge.test 
$ ping fugafgua.test
```

表示だけならばapache側のNameVirtualHostで振り分けるだけで完了します。

## nginx-proxyを使う

webさえなんとかなるのであれば[nginx-proxy](https://github.com/jwilder/nginx-proxy)のリバースプロキシを利用するのが最も簡単です。

docker-compose経由で簡単に導入できます。

```
nginx-proxy:
  image: jwilder/nginx-proxy
  ports:
    - 80:80
  volumes:
    - /var/run/docker.sock:/tmp/docker.sock:ro

web1:
  environment:
    VIRTUAL_HOST: "web1.localhost, web3,localhost"

web2:
  environment:
    VIRTUAL_HOST: "web2.localhost"
```

enviroment.VIRTUAL_HOSTで割り当てるホスト名を指定します。

複数の指定やワイルドカードの指定も可能です。

上記設定の場合は次のような設定となります。

- http://web1.localhost/ , http://web3.localhost/ -> web1
- http://web2.localhost/ -> web2

NameVirtualHostも不要となるため、webのみで良ければこちらが良いです。

pingなど、名前解決が必要となる場合はdnsmasqを利用しましょう。

```
$ ping web1.localhost
```
Expo + Notification を初めてみる

# MacがないけどIphoneに通知が送りたい！
アプリ開発の授業中にふとこんな思いが胸中を巡り、たどり着いたのは [**Expo**](https://expo.io/) でした。

Expo はJavaScript(フレームワークの主はReact)で簡単に Android, IOS のアプリを開発することを助けるツールです。

とりあえずアプリで通知を送る前に、まずはオンラインのエディタとCurlを用いて通知を送ってみたいと思います。

# アプリをインストールする
Iphoneで **Expo Client** をインストールして、アカウントをつくっておいてください。


# まずはオンラインエディタを使ってみる

Expoのオンラインエディタは、[Expo Snack](https://snack.expo.io/) というサイトで、ウェブで簡単に Expo のアプリケーションを作ることが出来ます。今回はCurlを用いて通知を送るために、`ExponentTokenID` というものを得るためのアプリケーション()を作ります。

ソースコードは次のようになります。これを `App.js` へ書いて下さい。(書いたもの https://snack.expo.io/@elect/device-push-token)


```javascript
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Permissions, Notifications } from 'expo';

//取得のためのコード
async function registerForPushNotificationsAsync() {

  //warningがでるのを防ぐためにtry catchを入れる
  try {

    const { status: existingStatus } = await Permissions.getAsync(
      Permissions.NOTIFICATIONS
    );
    let finalStatus = existingStatus;

    if (existingStatus !== 'granted') {
      const { status } = await Permissions.askAsync(Permissions.NOTIFICATIONS);
      finalStatus = status;
    }

    if (finalStatus !== 'granted') {
      return;
    }

    this.token = await Notifications.getExpoPushTokenAsync();
    // this.token = token
    //コンソールに出力
    console.log(this.token);

  } catch (error) {
    console.log(error);
  }
  return this.token;
}


export default class App extends React.Component {
  componentDidMount() {
    //呼び出し
    let token = registerForPushNotificationsAsync();
  }
  render() {
    return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>Open up App.js to start working on your app!</Text>
        <Text>token: {token}</Text>
      </View>
    );
  }
}
```
`{token}` で赤い線が出ていますが、無視して下さい。**上手く行きます**

# Expo Client経由でExpoアプリを見てみる。

Expo Snack の右側を見て下さい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147520/6a6cd4f3-e3bd-6af8-63f1-9533865b2838.png)

デバイスが見えますね。この `Run on your device` をクリックすると、ログインを求められます。
ログインすると、`Projects` という欄から使っているアプリを選択できるようになっているので、これを起動します。


アプリを開くと、
`token: ExponentPushToken[...] ` という文字が見られると思うので、こいつをメモして下さい。

メモしたものを使って Curl で通知を送ってみましょう。

# Curl を使って Iphone に通知を行う

**アプリを落としてから、**
お使いのターミナルで次のコマンドを入力して下さい。

```shell
curl -H "Content-Type: application/json" -X POST "https://exp.host/--/api/v2/push/send" -d '{
  "to": "ExponentPushToken[<yourtoken>]",
  "title":"hello",
  "body": "world"
}'
```

あなたのIphoneに素敵な通知が得られます。
# 参考

* [公式のPush Notification](https://docs.expo.io/versions/latest/guides/push-notifications/)
* [ExpoのPush Notificationsを使う](https://qiita.com/zaburo/items/e04c1698694c6018a731)
「移転しました」ページの作り方【Webサーバーの移転】

#404 Not Foundの代わりに、自作のページ、「移転しました」を表示させる
##概要
1. まずVisual Studio CodeなどでHTML文書を作成します。その文書には「移転しました。移転先はこちら」などと記述する。
2. ウェブサーバーからほぼすべてのHTMLなどのコンテンツを削除する。
3. アップロードする。
4. Apacheの**httpd.conf**の設定をいじくる。

##具体的に申しますと・・・

### VisualStudioCodeでHTML文書を作成する。
![2019-08-04 145151 404NotFoundページ作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112525/ba390ecf-7948-282a-62b7-df961932f118.png)

ちなみにウェブブラウザで表示させるとこうなる。
![2019-08-04 145151 404NotFoundページ作成2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112525/1fce6dc9-e5f2-63ea-aa22-a4cdf1b584cc.png)


###削除する
ほぼすべてのhtmlファイルを削除する。
index.htmも消しちゃいましょう。
`sudo rm /var/www/html/*`

###アップロードする
今回はTeraTerm経由でアップロードします。
![2019-08-05 404NotFound13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112525/8afc835f-603e-cf31-048d-4a59bc14e852.png)

SCP 送信先に /var/www/html/ と書き込んで、
![2019-08-05 404NotFound14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112525/54c558bf-f08f-7537-da8a-39bee171e53f.png)
Enterを押してください。



試しに保存先を表示してみた。
![2019-08-05 404NotFound16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112525/aafc6cfb-0aed-5611-49ba-fb21f79d7756.png)
404NotFound.htm以外のhtmlファイルも削除してあります。


###httpd.confをいじくる。
`sudo nano /etc/httpd/conf/httpd.conf`と入力する。
![2019-08-05 404NotFound6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112525/a44c6978-56f3-bc30-bb93-aa6573555d18.png)
すると↑のように表示されると思う。

この設定ファイルのうち、

＃ErrorDocument 404ではじまる行に注目する。
＃を外してください。それから、
`ErrorDocument 404 /404NotFound.htm`と入力する。
![2019-08-05 404NotFound21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112525/0fcf0c49-5a3e-ac67-f0b9-4230f3b56af8.png)


Ctrl ＋ x を入力し、
![2019-08-05 404NotFound8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112525/edf531c9-0647-5fff-ed29-7fd2ede16cee.png)
Enterを押して

![2019-08-05 404NotFound9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112525/59579d3b-4cff-0ec6-899e-200a9153f64e.png)
もう1回Enterを押して下さい。

`service httpd restart`と入力します。
![2019-08-05 404NotFound18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112525/ba273360-fc95-588b-6ce4-4adf00809ccb.png)

パスワードを入力して下さい。
![2019-08-05 404NotFound20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112525/b30beac0-6405-a65e-eb9a-f2fe00b9cff7.png)



すると、ブラウザで適当にhtmlファイルへのURLを入力しても、
「移転しました。」と表示されるのです。
![2019-08-05 404NotFound17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112525/eec053ef-6aaf-2cb4-b378-31c8d18fa718.png)


おしまい。

##余談ですが・・・
試していませんが、おそらく403 Forbiddenのページも何らかの「移転しました」っていう移転通知のHTMLファイルに差し替えれば何らかのcgiにアクセスした場合もちゃんと案内できるんじゃないでしょうか。
後輩の独り立ちのために「新卒からの質問をソシャゲっぽい仕組み」をマネしてみたら捗った話

# はじめに

今まで後輩と2人でやっていたプロジェクトが後輩1人でやる事になって(私が離任になって)不安がっていたので以前qiitaで読んだ下記の記事を実践することにしました。

[新卒からの質問をソシャゲっぽい仕組みにしたら捗った話](https://qiita.com/ysktsuna/items/fced3a9515c8f585ca50)

おかげ様で今のところ上手くいっています。
そして下記の記事をみたので、自分も記事を書いてみました。

[新人研修で質問スタミナ制を導入してみた](https://qiita.com/takkii1010/items/b491eee6b835a3b4a99d)

# 内容

## 準備
当初は付箋を考えていたのですが、貯金が趣味だそうなので、少しでも本気になってもらえるように本物の金貨のようのように質感のある、金色の金属のおもちゃコインを選びました。(楽天で探して3000円(自腹:persevere:)でした)
![coin200.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128663/7ad7a264-cfb7-4cf3-40d7-bd0d8eeb865a.jpeg)

あとコインを使う時はガラスのビンに入れるようにして「チャリーン」と音をさせて、使用感を出すようにもしました。

![jar200.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128663/be2d374a-188a-c29c-897d-50b5b1b72ae3.jpeg)



## ルール

- まずチームのリーダーと話し合って1ヶ月(20人日)で自分が捻出できる稼働が2人日(15時間)という取り決めをしました。
- そこからコインが30枚なので、コイン1枚30分という単位になりました。
- 強制的に毎日話すタイミングを作るため、毎朝出社したらコイン1枚渡すログインボーナス制にしました。
- 営業日が20日で1ヶ月に30枚配るには、ログインボーナスの1日1枚では配りきれないので、月初に10枚まとめて渡す事にしました。
- 質問をしない(自分で考え抜く)ことのインセンティブとして、質問しなかった次の日はボーナスコインを渡すルールも追加しました。

### 全ルール
>・月初に10枚支給
>・ログインボーナスで毎日1枚支給
>・ログインボーナスは日の最初の処理
>・コイン1枚で30分の質問タイム
>・たとえ1分でもコイン1枚必要
>・30分を超えたらコイン1枚追加してから継続
>・コインを使わなかった日の次の日は+1枚ボーナス
>・コインの上限は30枚
>・こちらの本業が忙しい場合はコインは使えない

## 結果
今年の4月から始めて、4月5月はそこそこコインを使いましたが6月にはコインがカンストしてしまいました。
成長して、ほぼ独り立ちができた、と言ってもいいと思います。
※ただし2人で実施する決まりのある本番作業等があるので完全に1人ではできない状態です。

## 実施例

- (ログインボーナスを渡す時に)
:woman_tone1:＜「ちょっと質問あるんですが、今日は時間ありますか？」
:grinning:＜「午前中ならいいよー」

- (簡単な質問をした時)
:grinning: ＜「このように、これをこうすればできます。(カタカタカタッ、ターン！)」
:woman_tone1:＜「まだ時間があるので、追加で質問します！」

- 調査が必要な質問の時
:grinning:＜「その調査だとたぶんコイン1枚じゃ足りないな。3枚ぐらい使うけど本当にやる？」
:woman_tone1:＜「・・・もうちょっと自分で調べてみます」

## 振り返り
- 質問のタイミングを確認や調整したり、質問をまとめたり、自分で考えるようになったり、ルールの狙い通りの効果が出たように思います。
- こちらができるのは仕組みを用意するだけで、成長には本人の努力が一番重要だと思います。

>・たとえ1分でもコイン1枚

このルールは後から追加したのですが「ちょっとだけ」の質問が激減したので、こちらとしては凄く助かりました。
別プロジェクトの作業を一旦止めて、また再開するのに割とエネルギー使うんですよね。


## おわりに

@ysktsuna さん、@takkii1010 さん、参考になるを記事本当にありがとうございました！
配列の書き方

# はじめに

PHPで配列を書く時

```php:php
$array = [
    "foo" => "bar",  
    "bar" => "foo",  
];
```
のような書き方が主流だと思う。しかし、PHP 5.4以前のバージョンでは上記の記述はできず、

```php:php
$array = array(  
    "foo" => "bar",  
    "bar" => "foo",  
);
```

と記述する必要がある。なお、PHP 5.4以降のバージョンでも後者の書き方は許可されている。

[PHP: 配列 - Manual](https://www.php.net/manual/ja/language.types.array.php)

# 先日の出来事

CakePHP2を使って作ったサイトを本番環境に移行する作業をしていた。本番環境に移行後、下記のエラーが大量発生！

```:error
Parse error: syntax error, unexpected '[' in x.php on line x
```

あら…

本番環境はPHP5.3だから確かに`$array = [];`表記はエラーになる…でも

[インストール - 2.x](https://book.cakephp.org/2.0/ja/installation.html)

によると、CakePHP2はPHP 5.3.0以上をサポートしているから、`$array = [];`表記はしてないはず…

# 調査結果

開発者が追加したコードに`$array = [];`表記が大量に混じっていた。そして開発環境のPHPバージョンが5.4であったため、開発中はエラーにならなかった。

なんと…
エラー箇所を全て修正する？
でも開発環境と本番環境でPHPのバージョンが違うなら、他にもエラーが出る可能性も…

# 結果

本番環境のPHPバージョンを5.4にすることで解決。

# 所感

開発環境の定義をしっかりと行う！
Azure Red Hat OpenShiftをデプロイする　～そして失敗～

# Azure Red Hat OpenShiftが実装されたので試してみた。

フルマネージドのOpenShiftサービスっていう事で、気になったので早速デプロイしてみましょう。


概要はこちら→（https://azure.microsoft.com/ja-jp/services/openshift/）

###AzurePortalからぽちぽち選択していくよ
<b>1:ダッシュボード→リソースの作成→Managed Openshift on Azureで検索</b>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477780/2ab620fd-c329-3822-01a5-688e6997cc08.png)


<b>2:二種類のうち、どちらかのプランを選択して作成します。</b>
今回はデフォルトにしました。
二種類の詳細は以下から

- Bring your own VNET
 - Simple proxy resource for OpenShift on Azure.

- default
 - Contains simple proxy resource for OpenShift on Azure

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477780/479b89fb-7c1b-3336-4a34-dbc6c875ca0a.png)

<b>3:その他の必要情報を適宜入れていきます。</b>
ちなみにまだ日本リージョンにはデプロイが出来ませんのでご注意を
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477780/6d0e28af-fe07-17fa-2427-d3819597fd57.png)

# そして失敗する。
何故だー！！
conflictエラーだから何と衝突しているんだろ。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477780/5b1c03dd-5c0b-264e-ecde-1ca81008d20c.png)


# ちゃんと前提条件を確認しよう。

以下抜粋
>Azure Red Hat OpenShift アプリケーション ノードの予約インスタンスを購入する
>Azure Red Hat OpenShift を使用する前に、Azure Red Hat OpenShift の予約アプリケーション ノードを 4 個以上購入する必要があります。その後に、クラスターをプロビジョニングできるようになります。
>Azure をご利用の場合は、Azure portal から Azure Red Hat OpenShift 予約インスタンスを購入します。 購入後、24 時間以内にサブスクリプションが有効になります。

詳細は↓
https://docs.microsoft.com/ja-jp/azure/openshift/howto-setup-environment#purchase-azure-red-hat-openshift-application-nodes-reserved-instances

# 次回予告
時間があれば、予約購入もして、実際のデプロイまで
通信／ネットワークについての基本【その１】コンピューターネットワークについて

##はじめに

普段何気なく使っている**インターネット環境**:computer:
具体的にはどのような仕組みで成り立っているのかを整理する意味でも、記事を書いてみようと思います:writing_hand_tone2:

##コンピューターネットワーク

コンピューターとコンピューターをつなげると、コンピューターネットワークになります。コンピューター同士が繋がり合って情報をやりとりできるようになった状態です。

:bulb:**LAN**(Local Area Network)
  　大学や研究所、企業内や家庭内など同じネットワーク内にあるコンピューターをつなげたネットワークのこと
:bulb:**WAN**(Wide Area Network)
    　会社の支店間など、地理的に離れたコンピューターをつなげた比較的大規模なネットワークのこと
:bulb:**インターネット**
    　複数のLANやWANをつないだ地球規模のネットワーク
:bulb:**イントラネット**
    　　地域限定版のLANのこと。特定の会社や地域内のコンピュータのみでデータをやり取りしたりできる。通常は外部からアクセスできないようにセキュリティがかかっている。
　　　 


##コンピューターネットワークでできること

- 電子メール
- チャット
- ファイル共有
- 周辺機器接続
- 分散処理
- ファイル転送
- 遠隔操作
- 動画・音楽配信
- WWW（Web）

##パケット交換方式と回線交換方式

**パケット交換方式**
コンピュータネットワークでの通信方式で、メールやファイルなどのデータをパケットと呼ばれる小さな単位に分割してやり取りします。
:small_orange_diamond:データを少しずつ送ることで回線の専有を避け、複数の相手と並行して柔軟に通信することができます。
各パケットにはどこへ届けるのかを表す**IPアドレス**が付けられます。


**回線交換方式**
アナログ電話や携帯電話の３G回線での通信方式です。
:small_orange_diamond:通信経路を専有し、基本的に1対1でしか通信できない通信方式です。

##TCP/IP　コンピューターネットワークの階層##
通信の送受信に関わる一連の作業をいくつかの段階に分けて行い、各段階を層（レイヤー）と呼びます。各層にはそれぞれルールが有り、そのルールに従って処理が行われます。

| 各層       　　　　|役割|
|:-----------------|:------------------|
| アプリケーション層  | Webや電子メール等のサービスをユーザーに提供 |
| トランスポート層    |送信されたデータを確実に届ける|
| インターネット層    |目的の機器へデータを渡す |
| ネットワークインターフェース層   |隣の機器にデータを渡す |

:bulb:**TCP/IP**
  　 一つのプロトコルを指す言葉ではなく、標準的なプロトコルをまとめて読んでいます。TCPとIPはその中でも代表的なプロトコルです。
TCP/IPがプロトコル群の総称であることを強調する場合は、**TCP/IPプロトコルスイート**(インターネットプロトコルスイート)と呼ばれます。
SlackApiでチャンネルリストを取得する

## SlackAPPに登録する

1. Appを作成
[Slack API: Applications \| Slack](https://api.slack.com/apps?new_app=1)

2. Tokenと権限を付与 
メニューから OAuth & Permissions を選択
OAuth Access Tokenを確認する
下部のScopesから権限を付与

今回はチャンネルリスト取得なので下記権限

```
Access user’s public channels
channels:history

Access information about user’s public channels
channels:read
chat:write:bot
```

3. APIを確認する
[channels.list method \| Slack](https://api.slack.com/methods/channels.list)

```
Method URL:	https://slack.com/api/channels.list
Preferred HTTP method:	GET
Accepted content types:	application/x-www-form-urlencoded


Argument	Example	Required	Description
token	xxxx-xxxxxxxxx-xxxx	Required	
Authentication token bearing required scopes.
```

## データを取得する
- Jsonで取得(Ruby)

```Ruby
require 'net/http'
require 'uri'
require "json"
require 'pp'

res = Net::HTTP.get(URI.parse('https://slack.com/api/channels.list?token=xxxx-xxxxxxxxx-xxxx'))


hash = JSON.parse(res)
channels = hash["channels"]
channels.map { |channel| puts "##{channel["name"]}" }
```
AtCoder Regular Contest 031 埋め立て

# AtCoder Regular Contest 031 埋め立て

https://atcoder.jp/contests/arc031/tasks/arc031_2


陸地の塊ごとに、キューの深さ優先探索で番号をつけていく。それらの全てと隣接した海のスペースがないかn調べれば終了。

```python
raw_input='''
xxxxxxxxxx
xoooooooxx
xxoooooxxx
xxxoooxxxx
xxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
xxxoooxxxx
xxoooooxxx
xxxxxxxxxx
'''



def ans():
    k=0
    m=list(map(list,raw_input.split()))
    w=len(m)
    h=len(m[0])
    m=[i+['x'] for i in m]+[len(m[0])*['x']]
    


    for y in range(w-1):
        for x in range(h-1):
            if m[y][x]!='o':
                continue
            dfs(y,x,k, m)
            k+=1
            if k>3:
                return 'No'



    for y in range(w):
        for x in range(h):
            for l in range(k):
                if l not in [m[y+i][x+j] for i,j in ((1,0),(0,1),(-1,0),(0,-1))]:
                    break
            else:
                return 'Yes'
    else:
        return 'No'
            

def dfs(y, x, num, m):
    que=deque()
    que.append((y, x))
    while que:
        y,x=que.popleft()
        for i,j in ((1,0),(0,1),(-1,0),(0,-1)):
            ny,nx=y+i,x+j
            if m[ny][nx]!='o':
                continue
            m[ny][nx]=num
            que.append((ny, nx))

```
powershell: パスワードベースの非対話な Azure へのログイン


本記事では、AzureRM (Az) モジュールをインストールした PowerShell 環境で、対話的なログイン画面を表示させずに、パスワード ベースで Azure にログインするスクリプトを紹介します。

以下のスクリプトでは AzureRm を利用していますが、Az でもコマンド名が変わるだけで手順は全く同様です。
各コマンドの AzureRm を Az に置換すればそのまま使うことが出来ます。

## Powershell ログイン用のアカウントを作成

このステップでは `url` と `pass` の二つのパラメータを対話的に与えます。

- `url`: アプリを一意に識別するのに使われる、ホームページの URL。適当に作成して構わない (e.g. `http://openjny.oracle.com`)。
- `pass`: パスワード。16 字以上の半角文字からなる文字列で、1 文字以上の記号/大文字/小文字を含む。

```powershell
# Login
Login-AzureRmAccount

# Select subscription
Get-AzureRmSubscription | Out-GridView -PassThru | Set-AzureRmContext

# Create an app for logging-in on powershell
$url = Read-Host "Enter app url (begins with http)"
$pass = Read-Host "Enter password (must be at least 16 characters long)" -AsSecureString

$app = New-AzureRmADApplication `
    -DisplayName "PowerShellLogin" `
    -HomePage $("{0}/PowerShellLogin" -f $url) `
    -IdentifierUris $("{0}/PowerShellLogin" -f $url) `
    -Password $pass
New-AzureRmADServicePrincipal -ApplicationId $app.ApplicationId
New-AzureRmRoleAssignment -RoleDefinitionName Reader -ServicePrincipalName $app.ApplicationId

# Output information for login
"Tennant ID:" + (Get-AzureRmTenant).Id | Write-Output
"App ID:" + $app.ApplicationId | Write-Output
```

入力に与えたパスワード、及び最終的に出力されるテナント ID と App ID の 3 つの情報がログイン時に必要となります。
これらの情報は、安全な場所に保存して置いて下さい。

## ログイン時

以下の 3 つの情報をパラメータとして与えます。

- `tenantId`: テナント ID
- `username`: App ID
- `password`: パスワード

セキュリティの観点からは、これらの値のハードコーディングは推奨されません。
適宜、環境変数から読み取るなどの対策を施して下さい。

```powershell
$tenantId = "<Tenant ID>"
$username = "<App ID>"
$password = ConvertTo-SecureString "<Password>" -AsPlainText -Force

$cred = New-Object System.Management.Automation.PSCredential -ArgumentList ($username, $password)
Login-AzureRmAccount -Credential $cred -ServicePrincipal -Tenant $tenantId
```
nginxをsrpmでカスタマイズしてオリジナルのrpmパッケージを作成する

# 概要

nginxをインストールした後にモジュールのカスタマイズしたり、ログの格納場所変えたりするのって面倒なのでsrpmを使ってオリジナルのrpmパッケージを作る方法を紹介します。

## srpmとは
「RPMパッケージを作成することが可能なソース」です。
srpmをインストールするとrpmを作るパーツが置かれて、それをいじればインストール時にその設定を読み込んでオリジナルのrpmが作れます。
そのrpmをインストールすれば、同じ設定を複数の環境に確実に構築出来ます。


## 環境
手順ではCentos7.1で実行してますが、6でも動くことは確認してます。
nginxは1.16を使用しますが、どのバージョンでもsrpmがあれば同様の手順で可能だと思います。ただ、バージョンによっては使えない機能があったりするのでそこは適宜確認してください。

## 手順

### 必要なパッケージをインストールする
nginxのrpm作成に必要なパッケージを先ずインストールします。

```
$ sudo yum install rpm-build
$ sudo yum install -y make
$ sudo yum install -y gcc
$ sudo yum install -y openssl-devel
$ sudo yum install -y  zlib-devel
$ sudo yum install -y  pcre-devel
```

### インストールするのに必要なユーザ作成
srpmをインストールする為に必要なbuilderユーザを作成します。
パスワードはお好みで忘れないようなのを設定してください。
```
$ sudo adduser builder
$ sudo passwd builder
```

ちなみに、builderユーザが無い状態でインストールしようとすると、こんなエラーメッセージがでます↓
<img width="686" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321507/ac04baf7-90be-6cdd-109e-cd5eb3510de1.png">
「rootを使用します」って出てるから作ることは出来るのかと思いきや、何も作成されてなかったので必須のようです。

### builderユーザに変更
ここからはbuilderユーザで操作しますのでユーザを変更してください。

```
$ su - builder
```
パスワードは先ほど設定したものです。

### nginxのsrpmをダウンロードする
wgetコマンドを使用してサイトからsrpmをダウンロードします。
ダウロード出来るならwgetでなくてもOKです。
今回は1.16を指定していますが、他のバージョンが良い場合はパスの最後の部分を変更してください。

```
$ wget http://nginx.org/packages/centos/6/SRPMS/nginx-1.16.0-1.el6.ngx.src.rpm
```

### srpmをインストールする
ダウンロードしたパッケージをrpmコマンドを使用してインストールします。

```
$ rpm -ivh nginx-1.16.0-1.el6.ngx.src.rpm
```
インストールが完了すると、「rpmbuild」フォルダが出来ています。

### いじり方の紹介
何がどのフォルダに格納されているか簡単に紹介します。
rpmbuildフォルダに格納されているのは2つのフォルダです。

・SOURCES
nginxインストール時に使用されるファイル等が格納されています。
例えばnginx.confの内容を変えてrpmパッケージを作成しインストールすれば変更した内容でnginx.confはインストールされます。他にもログローテート設定のファイルもあります。

・SPECS
nginx.specというファイルだけが格納されています。
build時にこのファイルを指定してrpmパッケージを作成します。SOURCESに格納されているファイルをどこに格納するかや、どういったファイル名にするか等が記載されています。
ここをいじれば、使用するモジュールを変更したり格納されるファイルのファイル名が変更出来ます。


### rpmパッケージ作成
好きなようにカスタマイズが終わったらいよいよbuildしてrpmパッケージを作成します。
下記コマンドを実行してパッケージを作成します。

```
$ rpmbuild -bb rpmbuild/SPECS/nginx.spec
```

作成が完了するとrpmbuild配下にフォルダがいくつか作成されており、その中で「RPMS」というフォルダの中にrpmパッケージが作成されます。
今回の例だと、下記が絶対パスです。
同じフォルダ内にdebuginfoと名前のついたrpmパッケージもありますが、こちらは不要です。

```
rpmbuild/RPMS/x86_64/nginx-1.16.0-1.el7.ngx.x86_64.rpm
```

あとはこのrpmパッケージを好きな環境でインストールすれば同じ設定のnginxを構築することが出来ます。


## 終わりに
上記内容だと、ファイル名の変更やnginx.confの設定変更の方法しか取り上げていませんが、サードーパーティー製のモジュールを事前に組み込んでおいたり、逆に使いたくないモジュールは無効化しておくといったことも可能です。
nginxを構築している方で、手動で設定変更を行うのが面倒な方は一度検討されてはいかがでしょうか。
react-native-elements error: Warning: React.createElement: type is invalid

#react-native-elements error: Warning: React.createElement: type is invalid


React Native elementsのバージョンが1.0〜になってからフォーム要素が変わった。なので以前のFormInput, FormLabel, FormValidationMessageを使おうとすると上記エラー。

・FormInput は Inputに改名。
・FormLabel は削除され Input のlabelプロパティに。
・FormValidationMessage は削除され Input の errorMessageプロパティに。

参考：[React Native Elements Input](https://react-native-training.github.io/react-native-elements/docs/input.html)

<br>
ナカノさんのKindle本:point_down:で学んでいる方は途中、FormInputのところで躓きます。とても良い本なのでこんな所で評価を落とすことはないのでフォローしておきます。
<a target="_blank"  href="https://www.amazon.co.jp/gp/product/B07L9BQ9K6/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=B07L9BQ9K6&linkCode=as2&tag=kokkahasan-22&linkId=80ff1106f641fd9c4f412e8f8d06c2ec"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&MarketPlace=JP&ASIN=B07L9BQ9K6&ServiceVersion=20070822&ID=AsinImage&WS=1&Format=_SL160_&tag=kokkahasan-22" ></a><img src="//ir-jp.amazon-adsystem.com/e/ir?t=kokkahasan-22&l=am2&o=9&a=B07L9BQ9K6" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />

利用例：1.単純なフォーム（改造）

```react
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import {
  Input,
} from 'react-native-elements';


export default class App extends React.Component {
  constructor(){
    super();
    this.state = {
      input:""
    }
    this.onChangeInput = this.onChangeInput.bind(this);
  }

  onChangeInput(input) {
    this.setState({input})
  }

  render(){
      return (
        <View style={styles.container}>
          <Input label="Name" onChangeText={this.onChangeInput}/>
        </View>
    );
  }
}

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

```
<br>

利用例：2.エラーバリデーションを行うフォーム（改造）

```react
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import {
  Input,
} from 'react-native-elements';


export default class App extends React.Component {
  constructor(){
    super();
    this.state = {
      input:"",
      hasError:false
    }
    this.onChangeInput = this.onChangeInput.bind(this);
  }

  onChangeInput(input) {
    if(input.length < 10) {
      this.setState({hasError: true});
    }else {
      this.setState({hasError: false})
    }
    this.setState({input})
  }

  render(){
      return (
        <View style={styles.container}>
          {this.state.hasError ? 
          <Input label="Name" errorStyle={{ color: 'red' }} errorMessage='最低10文字必要'
          onChangeText={this.onChangeInput}/>
          :
          <Input label="Name" onChangeText={this.onChangeInput}/>          
          }
        </View>
    );
  }
}

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

```
<br>
JavaScript 配列操作

よく使うけど、他の言語触ってると忘れがちなのでメモ。 

詳細や最新情報は[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array "Array - JavaScript | MDN")を参照してください。

# 配列への追加
追加には`push`を使う。

```JavaScript
let array = ["1st"];
array.push("substream"); // 2

console.log(array); // ["1st", "substream"]
```
PHPのように`array[] = "addition"`はできない。

# 配列から削除
配列の最後を削除する場合は`pop`、最初を削除する場合は`shift`を使う。

```JavaScript
let array = ["2nd", "3rd", "4th"];
array.pop(); // "4th"
console.log(array); // ["2nd", "3rd"]

array.shift(); // "2nd"
console.log(array); // ["3rd"]
```

また、位置を指定した削除には`splice`を使う。
引数の1つ目には開始位置、2つ目は削除する要素数を指定する。

```JavaScript
let array = ["5th", "6th", "7th"];
array.splice(1, 1); // ["6th"]

console.log(array); // ["5th", "7th"];
```
添字ではなく文字列で削除を行う場合は`indexOf`を使う。

```JavaScript
let array = ["8th", "9th", "10th"];
let index = array.indexOf("9th"); // 1
array.splice(index, 1); // ["9th"]

console.log(array); // ["8th", "10th"]
```

# 配列に挿入
また、`splice`は途中に要素を挿入することも出来る。
挿入を行う場合は引数の3つ目以降に追加する要素を指定する。

```JavaScript
let array = ["RED", "DistorteD"];
array.splice(1, 0, "HAPPY SKY"); // []

console.log(array); // ["RED", "HAPPY SKY", "DistorteD"]
```
引数の2つ目を0にしておかないと、要素を削除した上で挿入という動作になる。
gitからherokuにデプロイしてみる

# Heroku

まずはherokuにログインします。

```
$ heroku login
```

heroku上にプロジェクトを作ります。

```
$ heroku create (プロジェクト名)
```

heroku側はいったんこれでOK。
次にgitを設定します。

# git

ローカルリポジトリを作ります。
適当なフォルダを作ってコマンド上でそのディレクトリ内にいきます。

```
$ git init
```

ローカルリポジトリにファイルの変更を追加します。※1

```
$ git add (ファイル名)
```

ローカルリポジトリにインデックスに追加したファイルを登録します。※2

```
$ git commit -m "コメントもここに登録します"
```

gitのリポジトリのURLを登録します。

```
$ git remote add origin https://github.com/(ユーザ名)/(リポジトリ名)
```

もし、リポジトリのURLを変える場合は一度消しましょう。（remote 「origin already exists」などのエラーでググるなど）

```
$ git remote rm origin
```

最後にpushする。※3

```
$ git push origin master
```

※1,2,3は変更時も同様の手順になります。

# herokuのgit自動デプロイ設定を試してみる

（後で試してみます）

# herokuにデプロイしてみる

まずはherokuにデプロイできるように設定。

```
$ git remote add heroku https://git.heroku.com/(herokuプロジェクト名.git)
```

そしてデプロイ。

```
$ git push heroku master
```

・・・謎の「remote rejected」エラーが表示されます。これは、herokuに単純なHTMLファイルをデプロイしようしていたのですが、それはダメだということらしいです。phpの形にして、無事にデプロイが成功しました。

（この記事を参考にしました。 http://stackoverflow.com/q/7651/454997 ）
GitでUntracked filesなのに.gitignore効かない時の原因

# 前提

[gitignore.io](https://gitignore.io/)にて[Unity用.gitignore](https://gitignore.io/api/unity)をインポートしたプロジェクトでの出来事

# 症状

以下の`.csproj.meta`ファイルが`Untracked files`に現れたため`.gitignore`に相対フルパスを追記したが反映されなかった。

- `/Assets/Plugins/Zenject/OptionalExtras/ReflectionBaking/Zenject-ReflectionBaking.csproj.meta`
- `/Assets/Plugins/Zenject/OptionalExtras/Signals/Zenject\-Signals.csproj.meta`

_(UnityでZenjectをインポートした際に含まれていたファイルで、`.csproj`は各環境で生成すれば良いためignoreしていて、同様にUnity内で参照するための`.meta`ファイルもignoreしたという状況。)_

# 原因

上記`.gitignore`内に以下の記述があったため、そちらの設定が優先されていた

```
# Never ignore Asset meta data
!/[Aa]ssets/**/*.meta
```

`!`は明示的にignoreしないことを示すexcludeの記法

# 解決方法

Gitでは`.gitignore`ファイルの記述順で優先度が決まるらしく、上記のexclude記述の後ろに相対フルパスを書いたら無事反映された


# 最後に

「Git gitignore 効かない」とかでググると一度既にcommitされた歴史があるため`$git rm hoge`する必要があるよ、みたいな記事ばかりでこの視点にたどり着けなかったため、備忘録として残しておこうと思いました。
Java

#クラス
**public**
どのクラスからもアクセスできるということ

**static**
クラス特有の値やメソッドということ

**void**
戻り値なし

```Java
public static int aaa(int a, int b){
  # int ==> 戻り値型
　# aaa ==> 関数名
　# () ==> 引数
}
```

#読み込み
##Scanner
```Java
import java.util.Scanner;

Scanner sc = new Scanner(System.in);
```
##next
```Java
# 標準入力　dog cat bird

A = sc.nextLine();
System.out.println(A);  # ==> dog cat bird
# 改行まで読み込む(String型)

B1 = sc.next();
B2 = sc.next();
System.out.println(B1);  # ==> dog
System.out.println(B2);  # ==> cat
# 空白まで読み込む(String型)

# 標準入力  10 200

C1 = sc.nextInt();
System.out.println(C1);  # ==> 10
# 空白まで読み込む(int型)

C2 = sc.nextDouble();
System.out.println(C2);  # ==> 200.0
# 空白まで読み込む(double型)
```

#型変換
##数値型→String型
```Java
# int ==> String
String a = String.valueOf(127);

# double ==> String
String a = String.valueOf(123.45);

# long ==> String
String a = String.valueOf(127l);

# boolean ==> String
String a = String.valueOf(false);
```

##String型→数値型
```Java
# String ==> int
int a = Integer.parseInt(123);

# String ==> double
double a = Double.parseDouble(123);

# String ==> long
long a = Long.parseLong(123);

# String ==> boolean
boolean a = Boolean.parseBoolean(True);
# "true"、"TRUE"、"True"など大文字小文字を区別しない"true"のみtrueとなる。
# それ以外の値の場合は全てfalseとなる。
```
## 数値型→数値型
```Java
int x = 3
double a = (double)x  # ==> a = 3.0
# 変換したい数値の前に(型名)
```

#文字列
##StringBuffer
StringBufferクラスは、Stringクラス同様に宣言した変数に文字列を格納する。
Stringクラスとの違いとして、変数に文字列を格納したあとでも「値を追加」「挿入」「変更」などの、文字列操作が可能である。
StringBufferクラスは、文字列の値が「不変である」と分かっているときに、使用するケースが多い。

```Java
StringBuffer sb = new StringBuffer("dog");
# sb ==> 変数名
# () ==> 文字列

# 引数の文字列表現をシーケンスに追加
sb.append(abc);  # ==> dogabc
# ()内の型は何でも良い

# シーケンスの部分文字列内の文字を削除
sb.delete(1, 4);  # ==> dbc

# シーケンス内の指定された位置にあるcharを削除
sb.deleteCharAt(0);  # ==> bc

# 文字列表現をシーケンス内の指定された位置に挿入
sb.insert(1, "yui");  # ==> byuic
# 挿入する文字列表現の型は何でも良い

# 文字シーケンスを、シーケンスの順序を逆にしたもので置き換える
sb.reverse();  # ==> ciuyb

# シーケンスの指定された部分文字列内の文字を、指定されたString内の文字で置き換える
sb.replace(1, 3, "o46");  # ==> co46yb
```
##比較
```Java
String a = dog;
String b = cat;

if(a.equals(b)){
  System.out.println("Yes");
}
else{
  System.out.println("No");
}
```

```Java
import java.util.Objects;

String a = dog;
String b = cat;

if(Objects.equals(a, b)){
  System.out.println("Yes");
}
else{
  System.out.println("No");
}
```

#演算
##割り算
```Java
Math.ceil(10.4)  # ==> 11.0
# 切り上げ
# 戻り値は double 型

Math.floor(11.6)  # ==> 11.0
# 切り捨て
# 戻り値は double 型

Math.round(12.5)  # ==> 13.0
# 四捨五入
# 戻り値は double 型
```
##累乗
```Java
Math.pow(a, b)  # ==> a^b
# a, b は double 型のみ
```

#配列
##ソート
```Java
import java.util.Arrays;
import java.util.Collections;

int[] A = {1, 3, 4, 2, 5};

Arrays.sort(A);  # ==> {1, 2, 3, 4, 5}
# 昇順

Arrays.sort(A, Collections.reverseOrder());
# ==> {5, 4, 3, 2, 1}
# 降順
```
Knativeとは

## はじめに
説明を求められ適当に答えたのですが、自信が無かったので追跡調査しました

## Knativeに対する誤った理解
Google Kubernetes Engine 上で動作するserverlessでコンテナを管理するサービス
Googleのサービスとして認識していました

## Knativeの個人的な理解
Googleが公開してるアプリケーションです
Kubernetesに導入することでserverlessでコンテナを管理出来る
GCPでもAWSでもオンプレでも、どのKubernetes環境にもインストール可能

## 誤解してた所
サービスではなくアプリケーション

## 結論
Knative自体はserverlessではなく、Kubernetes上にインストールして
コンテナをserverlessで管理可能にするプラットフォーム
触ってないので多々疑問点は残しつつ、以上です。
触る暇があったら感想書きます。
PHPのバージョン確認はphpinfoで行うのが確実

# はじめに
運用しているサイトでエラーが発生！解析のため、PHPのバージョンを確認したい。sshで接続してPHPのバージョン確認をしてみる。

```shell
[user@host ~]$ php -v
PHP 5.6.8 (cli) (built: May  6 2015 02:27:31) 
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
[user@host ~]$ 
```
よし！PHP5.6だ！！

…

違う！！(こともある)

`php -v`で確認できるのはcliで稼働しているPHPのバージョンであり、Apacheで稼働しているPHPのバージョンは違うかもしれない。また、ドメインやサブドメイン単位でPHPのバージョンを切り替えて運用している場合もある。ではどうすれば正確なPHPのバージョンを確認することができるのか…

# phpinfoで確認する

```php:phpinfo.php
<?php
phpinfo();
```

DocumentRoot配下にphpinfo.phpを配置し、HTTPSでアクセスして確認するのが確実。
**※確認が終わったらphpinfo.phpの削除をお忘れなく**

# XSERVERの場合

**サーバーパネル** > **PHP** > **PHP Ver.切替**
から、ドメイン単位でPHPのバージョンを確認、変更ができる

### 2019/8/5時点で選択できるPHPバージョン
- PHP7.2.17 （推奨）
- PHP7.1.28
- PHP7.0.33 （非推奨）
- PHP5.6.40 （非推奨）
- PHP5.5.38 （非推奨）
- PHP5.4.16 （非推奨）
- PHP5.3.3 （非推奨）
- PHP5.1.6 （非推奨）

# 自作Ubuntsサーバーの場合

下記コマンドで有効になっているモジュールを確認する

```bash
a2dismod php <tab>
a2dismod php7.3
# PHP7.3モジュールが有効になっていることが分かる
```

※CGI版のPHPが稼働する場合は、直接コンフィグファイルを確認する。




# 参考

composerやLaravelの`artisan`、CakePHPの`bake`などはcliで実行するため、上述の`php -v`でバージョン確認を行うのが適切。

# リンク
- [PHP: phpinfo - Manual](https://www.php.net/manual/ja/function.phpinfo.php)
setIntervalではどこの間隔を指定しているのか

皆さん御存知の通りsetIntervalでは定期的に関数を呼び出してくれます。
しかしどこの間隔を指定してるのでしょうか？考えられる２つとしては次のものがあります
1. 呼び出し開始の間
2. 関数が戻ってきてからの時間

わかりやすくsetTimeoutでこの2例を書くとこのようになります

```javascript
// 1. 呼び出し開始の間
function one() {
  setTimeout(one, 1000)
  // 処理
}

// 2. 関数が戻ってきてからの時間
function two() {
  // 処理
  setTimeout(two, 1000)
}
```

# tl;dr

最短1だが、タイマの構造上？2

1のように動かすためには細かいタイマーを回しておけばよさそう(see [node.jsでchromeのように動かすためには](#nodejsでchromeのように動かすためには))

# 調べる方法
このソースを実行させて、``wait for :``がだいたい800msか1000msかで調べます

```javascript
let prevEnd = 0;

setInterval(() => {
    const now = new Date();
    const finish = now.getTime() + 200;
    console.log("wait for :" + (now.getTime() - prevEnd) + "ms");
    while (finish > new Date().getTime());
    prevEnd = new Date().getTime()
}, 1000);
```
# 結果
## node.js
混在しましたが、主に1000ms

```
node test.js 
wait for :1564983073657ms
wait for :804ms
wait for :1002ms
wait for :1002ms
wait for :1005ms
wait for :1004ms
wait for :1002ms
wait for :1004ms
wait for :803ms
wait for :1003ms
wait for :1005ms
wait for :1003ms
wait for :1004ms
wait for :1004ms
wait for :1001ms
wait for :805ms
wait for :1000ms
wait for :1003ms
wait for :1001ms
wait for :1002ms
wait for :1002ms
wait for :1004ms
wait for :804ms
wait for :1004ms
wait for :1000ms
wait for :1003ms
```

## chrome
大体800ms
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152617/0c30b7b2-5e6c-a069-94f0-db9a9d9aa54b.png)

# node.jsでchromeのように動かすためには
混在する理由はなぜだろうと思い次のようにしたらchromeのように動きました。

```javascript

let prevEnd = 0;

setInterval(() => {
    const now = new Date();
    const finish = now.getTime() + 200;
    console.log("wait for :" + (now.getTime() - prevEnd) + "ms");
    while (finish > new Date().getTime());
    prevEnd = new Date().getTime()
}, 1000);

setInterval(() => {}, 100);

```
VSCodeでvue-property-decorator使用時のsnippet作成



vue-property-decoratorの使用時にVSCode拡張機能のVeturのsnippetがいい感じに機能してくれないので作成。

macの場合
1. `Code->基本設定->ユーザースニペット`から`vue-html`を選択
2. 以下のjsonを貼り付けて保存

```json

{
	"vue-property-decorator": {
		"prefix": "vpd",
		"body": [
			"<template>",
			"\t$0",
			"</template>",
			"",
			"<script lang=\"ts\">",
			"import { Vue, Component } from 'vue-property-decorator'",
			"",
			"@Component",
			"export default class $TM_FILENAME_BASE extends Vue {}",
			"</script>",
			"",
			"<style lang=\"scss\" scoped></style>",
			""
		],
		"description": "vue-property-decorator snippet"
	}
}
```

vueファイル上で`vpd`をタイプするとスニペットが出てきます。

確認してませんがWindowsも同じ手順で設定できると思います。
細かい部分は自分好みに修正すると良いと思います。