OmniAICreator/Qiita-1.07M huggingface dataset:
古いバージョンのPHP・Perlで構成されたシステムをWindows Server 2016 IISで動作させるメモ

元環境
Windows Server 2003
IIS 5.0

新環境：
Windows Server 2016
IIS 10.0

下記バージョンを動作させたい：
php5.2.6nts


動作が確認できるまでに参考になったサイト：
IIS初期設定
http://www.mztm.jp/2017/10/12/windows10iisphp/
php.iniの設定
https://symfoware.blog.fc2.com/blog-entry-1077.html


PHP過去バージョンのダウンロード参考：
https://jmatsuzaki.com/archives/15515


今後の参考予定：
https://nasunoblog.blogspot.com/2010/03/php-iis75fastcgiphp.html
https://uzulla.hateblo.jp/entry/2013/08/16/010814
http://guitarfish.wazure.jp/index.php?IIS%E3%81%B8%E3%81%AEPHP%E8%A8%AD%E5%AE%9A%E6%96%B9%E6%B3%95%28IIS7.5%20x%20PHP5.2.11%29
https://server-network-info.blogspot.com/2017/02/windows-server-2016-iis-100-php.html


MySQLのインストール
mysql-essential-5.0.27-win32.msi
MySQL移行はダンプで行う
移行元で実行：
mysqldump -h localhost -u root -p --default-character-set=utf8 ﾃﾞｰﾀﾍﾞｰｽ > d:\databaseMysql
移行先で実行：
mysql -h localhost -u root -p ﾃﾞｰﾀﾍﾞｰｽ < d:\databaseMysql

PHPからMySQLを接続テスト

PEARのインストール
http://shopyuta.com/archives/2014
https://so-zou.jp/web-app/tech/programming/php/library/pear/introduction/install.htm
PEARインストールできないとき
http://shopyuta.com/archives/2014

★PHP修正
■php.ini関連のエラー
・SQL接続コードでのエラー
https://www.javadrive.jp/php/mysql/index1.html
http://books-nekoya.jp/Programming/MySQL/php.html

・下記のコードでエラーが発生した。
mb_language("ja");
mb_internal_encoding("SJIS");
mb_http_input("SJIS");
mb_http_output("SJIS");
⇒日本語環境のエラー
https://webkaru.net/php/mbstring-php-ini/

■5.2.5 から 5.2.6 NFSにバージョンを変えた影響のせいか通常動作の挙動ではなかった。
下記作業で改善された

■parse_ini_fileを使っている元のiniファイルを修正
例）
smtmail = addmail = aaa@test.com
⇒
smtmail = aaa@test.com
addmail = aaa@test.com

■コード全体の修正
html内のPHP文字表示部分修正
value="<?= $_username ?>"
 ⇒ value="<?php echo $_username; ?>" 

★Perl5.8.8の移行
・移行元のPerlフォルダをコピーしてくる。インストール不要。
・Pathを通す
・IISから.*cgi .*plのハンドラーマッピングに登録する
http://guu.fmp.jp/archives/5788
・この時点でPerl時点の動作は確認。
・HTTPエラー対応
「HTTP エラー 502.2 - Bad Gateway
指定された CGI アプリケーションは、正しく動作しませんでした。HTTP ヘッダーの完全なセットが返されませんでした。返されたヘッダーは "Can't locate ./get_form.txt in @INC (@INC contains: C:/Perl/site/lib C:/Perl/lib .) at ・・・」
通知	   ExecuteRequestHandler
モジュール	   CgiModule
エラー コード	   0x00000002

・移行したPerlファイルのrequireでエラーコードが出ていたので、requireする直前に下記のコードを加えると動作

```x.pl
if($0 =~ /^(.*[\\\/])/) {chdir($1);}
require 'xxx.pl';
```

★Hyper-Vテスト環境から本番環境への移行時の問題
チェックポイントなど作成したので、ファイルがバラバラになった。
単一ファイルからドライブの接続ができるようにチェックポイントを削除して、終了しておく。
https://uncle-atsushi.com/hyper-v_avhdx_delete

★新環境IISにSSL設定
https://www.ipentec.com/document/windows-windows-server-iis-setup-https-site
Docker-composeで手軽に自前のHackMDを立ち上げてみる

# これは何？
私の技術メモです。

Dockerのコマンドとか調べてみたけど、いまいちピンと来ないので、
とりあえず何かサービスを立ち上げてみて楽しさとか利便性を感じてみたい。

# やってみること
https://hackmd.io/
このサービスをDockerを使ってクラウドではなく自分のPCで立ち上げてみたい。
あまり細かいことは考えず、最低限で作業する。

> HackMD
マークダウンでドキュメントを書き、共有や共同編集ができる。
この技術メモの目的とはそんなに関係無い。

クラウドでも利用できるが、GitHubにDocker-compose.ymlが上がってるので、それを使わせてもらえば自分の環境に建てたサーバで利用ができる。
https://github.com/hackmdio/codimd
ここからgit cloneしてDocker-composeを使ってみる。

> Docker-compose
複数のコンテナを自動的に立ち上げてくれる。
今回目的とするHackMDはWebサーバとDBサーバが必要なので、Docker-composeを使えばWebサーバとDBサーバ用のコンテナが自動的に作られる。
Docker-compose.ymlというyaml形式の設定ファイルをもとに動く。

# 前提
PCのOSはWindows10です。
DockerホストはVagrantで立ち上げた仮想のubuntuとする。

# やってみた
### vagrantでubuntuを立ち上げる
今回の目的とそんなに関係無いので割愛。
とりあえず```C:\vagrant\ubuntu```で```vagrant up```した想定とする。

### Dockerをインストール
ここからはubuntuにssh接続でログインして作業。

```
sudo apt update
sudo apt install docker.io
```

### インストールできたことを確認

```
docker --version
Docker version 18.06.1-ce, build e68fc7a
```

### githubからclone

```
git clone https://github.com/hackmdio/docker-hackmd.git
cd docker-hackmd
```

### Dockerをサービス起動

```
sudo service docker start
```

### Docker-composeで一気にHackMDを起動

```
sudo docker-compose up
sudo: docker-compose: command not found
```
失敗。
docker-composeは別で入手する必要があるので、docker-composeもinstallしてから気を取り直してup！

```
sudo apt install docker-compose
sudo docker-compose up
```
```docker-compose up```がちゃんと動いたら、少し時間が掛かります。
```listening at port 3000```的なメッセージが出れば恐らく待ち受け状態になっている。
見てわかる通り、今回はWebサーバはポート3000で待ち受けている。

### アクセスしてみよう

http://ubuntuのip:3000

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/145628/a2b3e7d5-5773-4805-30f1-edf134a70d5e.png)

### 動いた！

適当にアカウントを作ってサインインすれば、当然使えます。

![キャプチャ2.PNG](https://qiita-image-store.s3.amazonaws.com/0/145628/c3f1121f-9819-2e7d-39af-e059fc46f1d1.png)

作ったアカウントは記録されるし、作成したドキュメントは消えないし、コンテナを削除したりubuntu自体を再起動しても、```docker-compose up```し直せばちゃんと残っている。

### 補足

大まかに、Docker-composeの中で

* コンテナイメージの取得
* コンテナの生成
* コンテナの起動(ボリュームマウント含む)

をやってくれている。
Dockerホストであるubuntuの上に、瞬時にWebサーバとDBサーバ(postgre)を起動する。
DBサーバに書き込まれたアカウントやドキュメントなど、永続化する必要のあるものはローカルに保存されるようにマウントまでしてくれている。故にデータが消えない。すごい。
VSCodeでAWS CloudFormation をYAMLで書くための個人的ベスト設定

[AWS DevDay 2018 AfterPartyの人気エディタ投票で1位になったVSCode](https://twitter.com/awscloud_jp/status/1058342977276325891)でCloudFormationを書くための個人的ベストな設定を紹介します。

AWSコンソールにも[JSON, YAML両方に対応したエディタ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/working-with-templates-cfn-designer-json-editor.html)がありますが、チェック機能の安心感はあるもののエディタとしての使い勝手では、どうしても普段使うエディタに劣ります。

普段使いのVSCodeにCloudFormationをYAMLで書くための設定を導入しましょう。

# 導入するもの

[YAML Support by Red Hat](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml)

`code` コマンドを使えば、一発です。

```sh
code --install-extension redhat.vscode-yaml
```

# 設定1

`settings.json` に以下の設定を追加します。
最近のVSCodeは設定画面をUIで出すようになったので、 ~~右上にある`・・・` からsettings.jsonを開くか、~~
コマンドパレットを開いて `>settings (JSON)` と打ち込んでsettings.jsonを開きます。

```json:settings.json
    "yaml.schemas": {
        "https://d33vqc0rt9ld30.cloudfront.net/latest/gzip/CloudFormationResourceSpecification.json": [
            "*.cf.yaml",
            "*.cf.yml",
            "cloud*formation/*.yaml",
            "cloud*formation/*.yml"
        ]
    },
```

`https://d33vqc0rt9ld30.cloudfront.net/latest/gzip/CloudFormationResourceSpecification.json` をYAMLスキーマとして登録しています。
これは、[AWS CloudFormationリソース仕様](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html)のアジアパシフィック (東京)へのリンクです。
このリソース仕様をファイル名が `*.cf.yml` または `cloud-formation` ディレクトリ以下のyamlファイルの場合に適用するという風に設定しています。

この辺りはCloudFormationファイルにどういった名前をつけるかの好みによるので、適宜変更して下さい。

# 設定1だけの問題点

<img width="412" alt="CloudFormationファイル例.png" src="https://qiita-image-store.s3.amazonaws.com/0/193814/89ff646a-02e7-3574-53f9-ea638336bd86.png">

`!Ref` などのカスタムタグを書いた箇所が`unknown tag <!Ref>`エラーに！！！

YAMLサポート拡張がCloudFormationで使える`!Ref`などのカスタムタグに対応していないのが原因です。

# 設定2

カスタムタグをYAMLサポート拡張に教えます。
以下の設定を`settings.json` に追加します。

```sh:settings.json
"yaml.customTags": [
    "!Ref",
    "!Sub scalar",
    "!Sub sequence",
    "!Join sequence",
    "!FindInMap sequence",
    "!GetAtt scalar",
    "!GetAtt sequence",
    "!Base64 mapping",
    "!GetAZs",
    "!Select scalar",
    "!Select sequence",
    "!Split sequence",
    "!ImportValue",
    "!Condition",
    "!Equals sequence",
    "!And",
    "!If",
    "!Not",
    "!Or"
  ],
```

# 結果

これでカスタムタグの問題に対応しつつ、YAMLサポートとAWS CloudFormationスキーマチェックをVSCodeで行える環境を手に入れました。

CloudFormationファイルの書き方自体は、下記の記事などが参考になります。

* [CloudFormationのススメ](https://qiita.com/y-ohgi/items/89f07e866713185799f5)
* [(2017年12月時点) 私的 CloudFormation ベストプラクティス](https://qiita.com/yasuhiroki/items/8463eed1c78123313a6f)
* [Amazon Web Services - Labs](https://github.com/awslabs?utf8=✓&q=cloudformation)
アジャイル宣言を理解すると、何が美味しいの？

2018/11/14追記

- これは、「アジャイル宣言」について自分の言葉でまとめたもので、３つのうちの１つです。
  - その１）[「アジャイル宣言とは？新しい価値観の提示 - Qiita」](https://qiita.com/gounx2/items/3efc7ddb7a8bc892bf50)
  - その２）「アジャイル宣言を理解すると、何が美味しいの？ - Qiita」（本記事）
  - その３）[「なぜアジャイル宣言が誕生したのか？何を変えようとしているのか？ - Qiita」](https://qiita.com/gounx2/items/b5381186856eb54e48c9)
- その１）２）３）の順に読むことを想定していますが、それぞれ単独でも読めます。


# これは何？

- アジャイル宣言の理解が重要だと思ったので、自分の言葉でこれを説明してみます。
  - もう少し詳しく書くと『アジャイル宣言とは、新しい価値観であり、判断基準であり、変わらないもの』であることを説明します。
  - 『アジャイル宣言の使い方』についても書いてみます。
- なお、この文書での「アジャイル宣言」とは以下の２つの原文を指します。
  - [『アジャイルソフトウェア開発宣言』](http://agilemanifesto.org/iso/ja/manifesto.html)の原文
  - [『アジャイル宣言の背後にある原則』](http://agilemanifesto.org/iso/ja/principles.html)原文


# アジャイル宣言を理解すると、何が美味しいの？

- アジャイル宣言とは一言でいうと「新しい価値観の提示」です。これを理解することで『自分たちがやっていることが良い？悪い？方向に向かっているのか？どこに向かえばいいか？を判断できる』ようになります。（現実のシステム開発はそんなに簡単なものではないので「判断できる」と言い切るのは大げさかもしれません。ですが、少なくとも「より良いシステム開発への道しるべ」にはなってくれるはずです）

- 例えば、いろいろなキーワード(スクラム、Docker、CI/CD など)について考えていると「結局何が重要なのか？どれを採用すればいいのか？」まるで、迷路の中で迷子になってしまうような感覚になってしまいます。そんなとき、アジャイル宣言（新しい価値観）という視点に立ち、改めて考え直すことで、迷路から抜け出すキッカケを与えてくれます。

# アジャイル宣言の役割/使い方

- ここでは「アジャイル宣言の美味しさが、自分たちのチームにどのようにもたらされるのか？＝アジャイル宣言の役割/使い方」について書いてみます。

## １．もしも、アジャイル宣言がなかったら？

- より良いシステム開発の為、新しいチャレンジとして自分たちのチームに、スクラムやDockerを導入しても、失敗してしまうかもしれません。
- なぜなら、どんな開発手法や技術を導入するかを判断する為の基準がないからです。
- ちなみに、自分たちのチームが問題を抱えていないなら、変える必要はありません。

![20181111-agile-1.png](https://qiita-image-store.s3.amazonaws.com/0/275337/bb20e7b9-cc08-781d-1a21-0c08e4191da9.png)


## ２．アジャイル宣言（＝新しい価値観）を受け入れられるなら？

- 皆が納得できる基準として、アジャイル宣言（＝新しい価値観）を受け入れられれば、自分たちのチームに合った、開発手法、技術を導入を選んで、導入することができます。
- 自分たちのチームに合ったものを導入するわけですから、導入失敗するリスクを減らせます。

![20181111-agile-2.png](https://qiita-image-store.s3.amazonaws.com/0/275337/7dfa9be2-6aa0-035e-da14-d9fb22d79eeb.png)

## ３．アジャイル宣言だけが、唯一変わらない

- アジャイル宣言では『チームを取り巻く状況の変化に合わせて、開発手法や技術＊も＊柔軟に変化させることで、成果を出し続けるソフトウェア開発が実現できる』と考えています。
- 状況も開発手法や技術もあらゆることが変化する前提ですが、そんな中で、唯一変わらないのは、アジャイル宣言（＝新しい価値観＝判断基準）です。

![20181111-agile-3.png](https://qiita-image-store.s3.amazonaws.com/0/275337/5d904c83-3d8f-37fa-403f-864e5fc2bbee.png)

# まとめ

- アジャイル宣言は『原点』なので『迷ったときに、初心に戻る』ことができそうです。

- アジャイル宣言を、さらにギュッと圧縮したものとして「モダンアジャイル」という考え方もあるようです。

- アジャイルを取り巻く環境はこんな感じでしょうか。

        ＜↑より抽象的：概念、理念（時間が経過しても変わらないもの）＞

            モダンアジャイル
            　｜
            アジャイルソフトウェア開発宣言
            　｜
            アジャイル宣言の背後にある原則
            　｜
            スクラム、XP などのソフトウェア開発手法
            　｜
            Docker、Kubernetes、CI/CD、マイクロサービス、
            Infrastructure as Code など

        ＜↓より具体的：技術要素（時間の経過とともに変化しやすいもの）＞

-  [『アジャイル・コーチが去ったその後で - 金融とIT英語のアレクシス』](https://www.alexys.co.jp/blog-2016oct/)より引用

        Don’t just do agile, be agile.
        "アジャイルで開発する、ではなくアジャイルな日常の中で開発せよ"
CentOS7 システム管理

システム起動の流れ
　①BIOS/UEFI　⇒　②ブートローダ　⇒　③カーネル　⇒　④init/systemd
 起動時のログ確認
　dmesg

①BIOS/UEFI
   OSの起動やPCと接続機器間の入出力を制御するプログラム
②ブートローダ
　HDDなどのストレージからOSを読み込んで起動するプログラム
③カーネル
　OSの中核プログラム

#④init⇒systemd
・initの仕組み
   1./etc/inittab ファイル読み込み
   2./etc/rc.sysinit　スクリプト読み込み
   3./etc/rc　スクリプト実行
   4./etc/rcスクリプトが「/etc/rc$ランレベル.d」ディレクトリ以下のスクリプトを実行

・initの欠点
  - デーモンやアプリケーション数が増えると、管理や制御が複雑になり、
  - initから起動される各種デーモンやアプリケーションは、並列処理が行われず、数が増えるとOS起動速度が遅くなる
  - 何らかの理由でプロセスの親子関係が崩れた場合に、子プロセスがinitプロセスの直接管理下に置かれるものの、子プロセスの挙動を適切に制御できない

・systemdの仕組み
処理をUnitという単位で管理
　　Unitとは
　　　1.スクリプトではなく設定ファイルであり、Unitの設定をもとにSystemdが処理実行
　　　2.Unit同士の関係を定義可能(例：AにはBが必要と定義すると、最適な起動順で起動)
　　　3.用途別にいろんな種類がある
　　　　 - .service プロセスの起動/停止に関する設定
　　　　 - .mount  ファイルシステムのマウント/アンマウントに関する設定
　　　　 - .target Unitをグループにしてまとめたもの
　Unitは「/usr/lib/systemd/system(インストール時の初期設定)」と「/etc/systemd/system(ユーザー個別設定)」にあり、両方に同じファイル名が存在する場合は「/etc/systemd/system」ディレクトリ配下の設定ファイルが優先される
　そのため、ユーザー独自のパラメータを指定したい場合は、「/etc/systemd/system/httpd.service/d」ディレクトリを作成し、配下に設定ファイルを作成する

   1.systemd起動
   2.default.targetの探索
   3.Unitの関係を解析
   4.プロセスの並列起動

・Systemdのメリット
  - アプリケーション側で起動・停止にかかるスクリプトの用意不要
  - 各種サービスのプロセス群を並列実行可能
  - プロセスをグループ化する「cgroup」という仕組みを使用して、プロセスの親子関係を管理しており、initよりも制御をより適切に行える

<コマンド例>
サービスの状態確認(例:httpd)
`systemctl status httpd`
サービスの起動(例:httpd)
`systemctl start httpd`
サービスの停止(例:httpd)
`systemctl stop httpd`
OS起動時にサービス自動起動設定(例:httpd)
`systemctl enable httpd`
OS起動時にサービス自動起動設定削除(例:httpd)
`systemctl disable httpd`
OS起動時にサービス自動起動設定確認(例:httpd)
`systemctl -t service is-enable httpd`

#runlevel⇒target
・runlebel
RHEL系だと0~6まである
  0 : 停止
  1 : シングルユーザー
  2 : 未使用/ユーザー定義可能
  3 : マルチユーザー、コンソールログインのみ
  4 :未使用/ユーザー定義可能
  5 : ランレベル3 + Xディスプレイマネージャ起動
  6 : リブート
  ※シングルユーザーモード　ネットワーク機能を起動しなく、rootでのみログイン可能なモード

・target
複数のサービス(デーモン)などの制御対象をグループにし、まとめたもの
例：network.target=ネットワークに関する処理の単位をグループ化したもの

<コマンド例>
デフォルトのtargetの確認
`systemctl get-default`
利用可能なtargetの確認
`systemctl list-units --type=target --all --no-pager`
デフォルトのtarget変更(graphical.targetへの変更例)
`systemctl set-default graphical.target`
 従来のrunlebelとtargetとの関係確認
`ls -l /lib/systemd/system/runlevel*target`
 システムブート時のサービス起動設定確認（これでrunlevel1ではNW起動されないのが確認可能）
`chkconfig --list`
OS再起動無しでtarget切り替え
`systemctl isolate multi-user.target`
runlevel確認(出力：変更前runlevel　現在runlevel)
`runlevel`
Chrome headlessをLambdaで動かす際の依存解消にCodebuildを使う

# はじめに
AWS LambdaでSeleniumを動かしたいというところに以下の記事を発見
https://qiita.com/nabehide/items/754eb7b7e9fff9a1047d

seleniumの依存を解消するのにどのみちAWSなのだからと、Codebuildで環境レスを試す

# 前提
* CodeBuildから読めるソースコード保持先（CodeCommit、Github等）
* CodeBuild結果の出力先S3
    * 注意 すべてのリージョンは揃えておくこと
* CodeBuildを設定できるだけのIAM権限

# ソースの準備
* ビルドスペックをソースディレクトリルートに用意  
serverless-chromeとchromedriver、pip(selenium)はこれで依存解決をする。

```yml:buildspec.yml 
version: 0.2

phases:
  install:
    commands:
      - mkdir -p bin/
      - pip install --upgrade pip

  pre_build:
    commands:
      - pip install -r requirements.txt -t .
      - curl -SL https://github.com/adieuadieu/serverless-chrome/releases/download/v1.0.0-37/stable-headless-chromium-amazonlinux-2017-03.zip -o headless-chromium.zip
      - unzip headless-chromium.zip -d bin/
      - rm headless-chromium.zip
      - curl -SL https://chromedriver.storage.googleapis.com/2.37/chromedriver_linux64.zip -o chromedriver.zip
      - unzip chromedriver.zip -d bin/
      - rm chromedriver.zip

  post_build:
    commands:
      - rm -rf .git/
      - rm .gitignore

artifacts:
  type: zip
  files:
- '**/*'
```
[original](https://github.com/tac-yacht/lambda_selenium/blob/master/buildspec.yml)

* lambda_function.py 作成  
    [参照元](https://qiita.com/nabehide/items/754eb7b7e9fff9a1047d#lambda_functionpy-%E4%BD%9C%E6%88%90)を参考に作る

# CodeBuildの設定
※設定画面の見出しごとに見出し
## プロジェクトの設定
### プロジェクト名
お好みで

## ソース
### ソースプロバイダ
GitHub  
### リポジトリ
GitHubで作ったときのPublic/Privateに合わせて設定
### リポジトリのURL
[ソースの準備](#ソースの準備)で準備したソースが入ってるリポジトリ

## 環境
### 環境イメージ
カスタムイメージ  
※ここでLambdaの実行環境がAmazonLinuxと[開発者ガイド][1] に記載があるの環境を合わせる
### 環境タイプ
* Linux
* その他の場所
    * aws/codebuild/eb-python-3.4-amazonlinux-64:2.1.6

### サービスロール
お好みで

## Buildspec
### ビルド仕様
buildspec.yml(デフォルト）

## アーティファクト
### タイプ  
Amazon S3
### バケット名
前提で準備したS3
### アーティファクトのパッケージ化
zip

# 使い方
S3にzipが作られるのでそのURLをそのままLambdaの関数コードへ投入してもよし、DLしてもよし

# 参考先
* https://qiita.com/nabehide/items/754eb7b7e9fff9a1047d
* https://dev.classmethod.jp/etc/codebuild-amazon-linux/
    * CodebuildでAmazonLinuxを使う方法
* [Lambda 実行環境と利用できるライブラリ][1]

[1]:https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/current-supported-versions.html
Visual Studio 2017 (15.9) のCMake機能でIntellisenseが効かなかった

# 

## 背景
- 研究で開発しているプログラムでCMakeを使っているが，Visual Studioを**Visual Studio 2017 15.9**にアップデートしたらcl.exeが使えなくなった
- 仕方がないのでVisual StudioのCMake管理機能を使い始めた
- Visual StudioのIntellisenseが効かなかった

## 目的
- Visual Studioで
- CMakeのプロジェクトを開き
- Intellisenseを使いながら
- 実装する

## 結果
できました．

## 何故Intellisenseを実行できなかったか？
問題点を書く前に，少しだけVisual Studioの仕組みについて説明します．

Visual Studioでは，C++のヘッダをincludeする際に二種類の記法があります．

```
#include <hahaha.h>

#include "hahaha.h"
```

**<>** を使用した場合は，IDEに設定された検索対象の場所から該当ファイルを検索します．この際，Windowsであれば，多くの場合IDEはVisual Studioとなるでしょう．そしてこのとき，Visual Studioのプロジェクトのプロパティから設定できる，*追加のインクルードディレクトリ* がここで言う**検索対象** のディレクトリとなります．

**""** を使用した場合には，呼び出し元ファイルを起点としてファイルを検索します．

私の環境における問題点は，自身が作成したローカルのファイルをインクルードする際に，**<>** を使用していたことでした．試しにこれを **""** に変更して試したところ，無事Intellisenseが動作しました．

## 予想
おそらく，これは**<>** を使用したことにより無駄に検索範囲が広くなってしまったため，それぞれのファイルを見つけ出すまでに膨大な時間がかかってしまっていたのではないかと考えています．

今回のプログラムはグラフィクス用のプログラムで，画面表示のためにたくさんの外部ライブラリを使用していました．そして，それぞれのライブラリのincludeディレクトリをIDEが検索する対象範囲に追加していたため，時間がかかってしまったものと思われます．
SQL 初心者のためのクエリ集（更新・構造操作系）

## トピック

- データの操作ではなく、DBやテーブル自体を更新したり、操作したりする系の基本的なクエリ集です。（自分用メモなので怪しい所が多々あるかもしれない）

- 以下の記事に基本操作をまとめています（Python コードと並べて）
    - [SQL と Pandas の対応表](https://qiita.com/takaiyuk/items/5232442eaeb01299b265)

- **Udemy の[こちら](https://www.udemy.com/standard-sql-for-beginners/)のコースで勉強していました。**

## データの更新

### 新規データの追加

- 新規データを1行追加
    - 列リストと、values句の値リストは、数が一致している必要がある。

```{sql:sql}
insert into
    TABLE (COL1, COL2, ...)
values
    (VALUE1, VALUE2, ...)
```

- 列リストを省略して新規データを追加
    - テーブルの前列に対して、値を指定する

```{sql:sql}
insert into
    TABLE  -- 3列のテーブルとする
values
    (VALUE1, VALUE2, VALUE3)
```

- 複数行を追加

```{sql:sql}
insert into
    TABLE (COL1, COL2, ...)
values
    (VALUE1, VALUE2, ...)
    (VALUE3, VALUE4, ...)
    (VALUE5, VALUE6, ...)
```

### データの更新

- ある列すべての値を更新

```{sql: sql}
set sql_safe_updates = 0;  -- safe モードの解除。実務ではあまり使わない

update
    TABLE
set
    COL = COL * 0.9;
```

- 特定の行のデータだけを更新

```{sql: sql}
update
    TABLE
set
    COL1 = COL1 * 0.9
where
    col2 > 1000;
```

### 行の削除

大量のデータ（10万件以上とか）を削除する際には予想以上に時間がかかるので注意

```{sql: sql}
delete from
    TABLE
[where
    条件式]  -- 削除する行の条件を指定できる。指定なしだとテーブルの全行を削除。
```

## DB構造の操作

### DBの追加・削除

- **DB確認**

```{sql: sql}
show databases;
```

- **DB追加**
    - 半角の英数字とアンダースコアで書く。
    - マジックナンバー（命名者しか意味が分からない数字）を使った名前は避ける。

```{sql: sql}
create database 
    DB_NAME;
```

- **DBの削除**

```{sql: sql}
drop database
    DB_NAME;
```

### テーブルの追加・削除・構造変更

- **テーブルの確認**

```{sql: sql}
-- use DB_NAME;
show tables;
```

- **列の確認**

```{sql: sql}
show columns from TABLE;
```

- **テーブルの新規作成**

```{sql: sql}
create table 
    TABLE_NAME(COLNAME1 DATATYPE not null auto_increment primary key,
               COLNAME2 DATATYPE not null);
/*
- not null: null を許可しない
- auto_increment: idを自動的に振る
- primary key: 主キーの設定
*/
```

- **テーブルの構造変更**

テーブルに列の追加

```{sql: sql}
alter table TABLE  -- 変更するテーブル名
add NEW_COL DATATYPE  -- 新しい列の列名とデータ型
after COL;  -- どの列の後ろに置くか
```

テーブルの列の変更

```{sql: sql}
alter table TABLE 
change OLD_COL NEW_COL DATATYPE;
```

テーブルの列の削除

```{sql: sql}
alter table TABLE
drop COL;
```

- **テーブルの削除**

```{sql: sql}
drop table 
    TABLE_NAME
```
xonshの設定ファイルをPythonの文法で記述する

xonshの文法は、Pythonを拡張しており、Shellとして使う時にはコマンドとPythonコードを混在させて記述でき、とても便利に使うことができる。

しかし、あくまでxonshの文法はPythonの拡張のため、Visual Studio Codeなどで.xonshrcを編集しようとすると、mypyや補完などと連携できない。設定ファイルを記述するときにも、これらのツールの恩恵が得られれば、よりxonshを拡張しやすいのにと考えていた。

問題は3つある。

* `$HOGE` で、環境変数を参照している。`$`はPython文法ではないためエラーになる。
* `$(hoge)``!(hoge)` で、PythonではなくShellとしてhogeコマンドを実行できる。`$()`はPython文法ではないため、エラーになる。
* `alias`関数は builtins.alias と、builtinsに直接追加されている。`from builtins import alias`としてもmypyではエラーになる。

そこで、Pythonの文法を逸脱しないように以下の2つを行った。

* `$(hoge)``!(hoge)`を使わず、[invoke](http://www.pyinvoke.org/)や、`builtins.__xonsh__.execer.eval(hoge)`を使って、コマンドを実行する。
* `$HOGE`を使わず、` builtins.__xonsh__.env`を使って環境変数をやり取りする。

つぎに、mypyで`builtins.alias`などのbuiltinsの拡張がエラーになる問題に対して、以下を行った。

* xonshオリジナルの`builtins.xxx`を使う場合、それを一つのパッケージでラップし、.xonshrcからは、そのパッケージを参照する。

以下のようなパッケージを作成した。

```py:xonsh_builtin/__init__.py
import builtins
import xonsh

x_env: xonsh.environ.Env = builtins.__xonsh__.env
x_execer: xonsh.execer.Execer = builtins.__xonsh__.execer
x_aliases: xonsh.aliases.Aliases = builtins.aliases
x_events: xonsh.events.EventManager = builtins.events
```

このパッケージを参照することにより、以下のように使える。

```py:.xonshrc
from .xonsh_builtin import x_env, x_aliases, x_execer

# 環境変数の取り回し
HOME = x_env["HOME"]
x_env["PATH"].append("{HOME}/bin")

# コマンドの実行
def __bookmark():
    name = run("cat ~/bookmark | peco").lines[0].strip()
    x_execer.eval(command)(f"cd {name}")
x_aliases["bk"] = __bookmark

# aliasesの利用
x_aliases["ll"] = ["ls", "-al"]
```

このようにPythonの文法の範疇で、xonshの設定を記述することができる。

ちなみに、私のxonshの設定ファイルは以下にあります。

https://github.com/74th/dotfiles/tree/master/xonsh

では、よいPythonShellライフを！
Git Hookについて - コミットワークフロー編

# 結論
1. `git commit`コマンドを実行しようとする
2. `pre-commit`が実行される
3. `prepare-commit-msg`が実行される
4. コミットメッセージ入力ができるようになる
5. `commit-msg`が実行される
6. コミットが実行される
7. `post-commit`が実行される

# はじめに
## 背景
Git Hookという便利な機能があるのに使いこなせなかった新卒情弱エンジニアはGit Hookを使ってみようと思った。
思いの外いろいろなところで処理を行うことができるのでここでまとめる。Gitの用語や使い方は[猿でもわかるレベル](https://backlog.com/ja/git-tutorial/)でまとめられているのでその知識があると仮定してこの記事を書く。

## そもそもGit Hookとは
Gitのアクションごとにクライアントサイドやサーバサイドでスクリプトを実行することができる。その機能のこと。

## この記事の目的
Git Hook未経験者がどのタイミングでフックを実行できるのか知ることができる。

## 事前準備
以降の内容を実際に実行するため、新規に任意名のフォルダを作成し、その中で`git init`コマンドを実行する。すると`任意名フォルダ/.git/hooks`が生成されているはずなので確認する(`.git`フォルダは隠しフォルダのため`ls -a`で確認できる)

# コミットワークフローフック
コミットワークフローフックには以下の4種類がある。

- `pre-commit`
- `prepare-commit-msg`
- `commit-msg`
- `post-commit`

`echo`コマンドを用いてどのようなタイミングで発生しているのか確かめてみる。
まず、`git add`、`git commit`してメッセージを入力する際に`:sh`してターミナルに戻った時の出力。

<img width="524" alt="スクリーンショット_2018-11-11_15_48_19.png" src="https://qiita-image-store.s3.amazonaws.com/0/212284/10e16696-dc34-fdc6-9d83-77e05a7f8b79.png">

すでに`prepare-commit-msg`まで進んでいることがわかる。次に、メッセージを入力してコミットした時の出力。

<img width="307" alt="スクリーンショット_2018-11-11_15_56_18.png" src="https://qiita-image-store.s3.amazonaws.com/0/212284/a9055aa5-0c4c-7ff6-f8d6-0837e3f65dcc.png">

`post-commit`まで進んでいる。では、実際のコミットはどの時点で行われているのだろうか。`commit-msg`ファイルの末尾に`exit 1`を追記して再度検証してみる。`test.txt`をステージングに追加し、コミットメッセージを入力した後、`git status`で状態を確認したものがこれ。

<img width="569" alt="スクリーンショット 2018-11-11 16.05.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/212284/7740f74a-3d88-d239-ac4e-0f84bce7334e.png">

`commit-msg`は行なっているにも関わらず、そこで1が返された結果コミットはされていないことがわかる。
最後に`commit-msg`ファイルの代わりに`post-commit`ファイルの末尾に`exit 1`を追記（`commit-msg`内の`exit 1`は消去）してコミットした結果は以下。

<img width="507" alt="スクリーンショット 2018-11-11 17.09.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/212284/d8653265-d506-c6b9-634b-90a59bdd00a2.png">

きちんとコミットされていることがわかる。よってコミットの流れと各フックのタイミングは以下。

1. `git commit`コマンドを実行しようとする
2. `pre-commit`が実行される
3. `prepare-commit-msg`が実行される
4. コミットメッセージ入力ができるようになる
5. `commit-msg`が実行される
6. コミットが実行される
7. `post-commit`が実行される
Angular.js の基本操作メモ

# Angular JSを使ったので簡単にメモ

### htmlとAngularJSの紐付け

```html:index.html
<html ng-app="index">
  <head>
    <!-- import Framework -->
    <title>テスト</title>
    <script src="./FrameWork/Angular.min.js"></script>
  </head>
<body>
...
</body>
</html>
```

```JavaScript:index_controller.js
var idx = anduler.module("index",[]);
```

### これで紐付けができる(なんとも明示的で良い)
第二引数のからの配列は色々な記事を見たところ以前のモジュールを引き継げるとかなんとか

## 次に要素の操作

```html:index.html
<body>
    <div ng-controller="hogehoge">{{hoge}}</div>
</body>
```

```JavaScript:index_controller.js
var idx = anduler.module("index",[]);

idx.controller('hogehoge',function($scope){
$scope.hoge = "test";
});
```

これで実行すると{{hoge}}がtestに変わる
$scopeで`ng-controller="~"`で定義した要素を取ってきているイメージ.{{}}の中身でhtmlの要素に簡単にアクセスできるので結構楽にかける．

---
今後の開発において多分タグの生成をJavaScriptに任してする可能性があると思ったから`ng-repeat`まで使ってみた．

###`ng-repeat`で回す時のデータは一次元配列にした．

```html:index.html
<body>
    <div ng-controller="hogehoge">
         <div ng-repeat="hoge in hogehoge">
             {{hoge.hoge}}
        </div>
    </div>
</body>
```

```JavaScript:index_controller.js
var idx = anduler.module("index",[]);

idx.controller('hogehoge'function($scope){
    $scope.hogehoge = [1,2,3,4,5];
});
```

これでやると1 2 3 4 5 が表示される
イメージはhtmlにhogehogeの名前をしたところに配列を渡す感じ

## Anguler.jsを使って見て
既存だと`document.getElementedById("id")`を毎度要素を持ってくるときに書かないといけなかったが,$scope.で中身の要素にアクセスできるあたりすごく楽にかけると思った.(コードが冗長的になりにくそうだと思った)
後，ng-~で色々な指定ができるみたいだけど，あまりその辺は触ってないから今後触っていきたい.
指摘や質問大歓迎です.
Herokuで「Precompiling assets failed.」と出たときの対処法

# 事象
以下のコマンドを実行し、herokuへデプロイした

```
git push heroku master
```

エラーが発生

```
Precompiling assets failed.
```

# 対応

以下のコードを
config > application.rbに追加

```application.rb
config.assets.initialize_on_precompile = false
```
CentOS7 ブートローダ周り

#CentOS7 ブートローダー GRUB2

###基本設定ファイル
```ruby:/etc/default/grub
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet"
GRUB_DISABLE_RECOVERY="true"
```

GRUB_TIMEOUT:GRUB2メニューが表示される時間(秒)
GRUB_DISTRIBUTOR:ディストリビューター名(デフォルト値：CentOS Linux)
GRUB_DEFAULT:タイムアウト時に起動するkernelを指定
※/boot/grub2/grub.cfgにおいてmenuentryから始まるkernel群が、最初を0として上から順番に数える(例：GRUB_DEFAULT=1)
※GRUB_DEFAULT=savedと記載すると、デフォルトのメニューエントリーがsaveされたものとなる
　saveされているエントリーは以下で確認可能
　`head -2 /boot/grub2/grubenv `又は
　`grub2-editenv list`
　変更する場合は`grub2-set-default 2`
　また、`GRUB_SAVEDEFAULT=true`を追記すると、前回選択エントリーがsaveされる
GRUB_DISABLE_SUBMENU:複数のカーネルをインストールしている場合、デフォルトでカーネルをサブメニューにグループ化するため、サブメニューにまとめて欲しくなくシングルメニューに戻したい場合に指定
GRUB_TERMINAL_OUTPUT:表示出力先を指定
GRUB_CMDLINE_LINUX:起動時にコマンドラインオプションへ追加したいオプションを指定
GRUB_DISABLE_RECOVERY:リカバリーモードのエントリー作成有無を指定

/etc/default/grubファイルを編集した場合は、grub2-mkconfigコマンドによって、設定ファイルの再生成が必要
・BIOSマシン
`grub2-mkconfig -o /boot/grub2/grub.cfg`
・UEFIマシン
`grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg`

GRUB_CMDLINE_LINUXの変更が適用されているかは、以下コマンドで確認可能
`cat /proc/cmdline`

###ブートメニューエントリ
 /boot/grub2/grub.cfgファイル

独自のブートメニューエントリを追加したい場合は、/etc/grub.d/40_customファイルを使用する。
/boot/grub2/grub.cfgファイルにならい、以下のように記述する。

```ruby:/etc/grub.d/40_custom
menuentry 'Custom CentOS Linux (3.10.0-862.11.6.el7.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-327.el7.x86_64-advanced-e4857c18-abfd-4b6a-86a2-ae9e7fd09a00' {
        load_video
        set gfxpayload=keep
        insmod gzio
        insmod part_msdos
        insmod xfs
        set root='hd0,msdos1'
        if [ x$feature_platform_search_hint = xy ]; then
          search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1'  343ddce6-1dee-4552-a0c8-090f9d275c92
        else
          search --no-floppy --fs-uuid --set=root 343ddce6-1dee-4552-a0c8-090f9d275c92
        fi
        linux16 /vmlinuz-3.10.0-862.11.6.el7.x86_64 root=/dev/mapper/centos-root ro crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet LANG=en_US.UTF-8
        initrd16 /initramfs-3.10.0-862.11.6.el7.x86_64.img
}
```

このままだと/boot/grub2/grub.cfgへ反映されず、起動時に選ぶことができない。
反映のために以下を実行する。
・BIOSの場合
grub2-mkconfig -o /boot/grub2/grub.cfg
・UEFIの場合
grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg
JavaScript、jQuery復習(文字カウント、テキストエリアにタグ挿入)

```ruby:qiita.rb
<div class="text tag">
 <h4>小説本文 ※10000文字まで</h4>
 <div class="arrange">
  <div class="jquery-button">
   <button type="button" class="bold">太字</button>
  </div>
  <div class="jquery-button">
   <button type="button" class="small-script">小字</button>
  </div>
  <div class="jquery-button">
   <button type="button" class="big-script">大文字</button>
  </div>
 </div>
 <div class="clearfix"></div>
 <p id="example">例： ＜strong＞<strong>文字が太くなる</strong>＜/strong＞</p>
 <div>
  <%= f.text_area :text, :maxlength => 10000,  class: "text-area area txt-field-2", id: 'txt-field-2', value: @draft.text %>
  <p class="count_num_2">現在0文字</p>
 </div>
</div>
```
```javascript:qiita.js
$(document).ready(この中にjQuery)
省略形　
$(function({この中にjQuery});
```
HTMLの読込が完了してからJQueryによる操作を開始するためreadyイベントを使用。　 

トリガー部分

```javascript:qiita.js
$(function({
 $(".trigger").click(function(){
  $(this).next().toggle();
 });
});
```
トリガー部分(".trigger")をクリックするたびに、(".trigger")の兄弟要素にあたる部分を表示、非表示にする。(this)を付けることでクリックされた(".trigger")のみ取得。

文字カウント

```javascript:qiita.js
$(function()
 $('.txt-field-2').on('keydown keyup keypress change', function(){
  //現在入力されている文字を取得
  var str = $(this).val();
  //取得した文字から改行を削除
  str = str.replace(/\n/g, '');
  //現在の文字数
  var strCount = "現在" + str.length + "文字";
  //リアルタイムで文字数を表示
  $(".count_num_2").html(strCount);
 });
});
```
on()メソッドで()内のイベントが発生した場合、関数内の処理を行う様に設定。
keydown:キーボードのキーを押したとき発生するイベント
keyup:キーボードのキーを離したとき発生するイベント
keypress:キーボードの文字キーが押されたとき、もしくは押され続けている時。
change:フォーム部品の状態に何らかの変化があったとき

機能ボタン：太字（フォーム内の一部の文字を太字にするための機能）

```javascript:qiita.js
$(function(){
 //txt-field-2というidをもつhtmlを探し出し、変数fieldに代入。
 var field = document.getElementById('txt-field-2');
 //挿入したいhtmlタグを配列として挿入
 var tag = new Array('<b>', '</b>');
 $(".bold").click(function(){
  //テキストエリアのカーソルの選択開始の位置を取得
  var start = field.selectionStart;
  //テキストエリアのカーソルの選択終了の位置を取得
  var end = field.selectionEnd;
  //選択テキストの長さ
  var selected = end - start;
  //選択テキスト
  //三項演算子を使い、変数selectedに値があれば、substrメソッドで開始位置をstartを引数とし、切り出す長さをselectedを引数としてテキストを選択
  var target = selected ? field.value.substr(start, selected) : '';
  //選択中のテキストを'<b>','</b>'で囲むように設定し、valueメソッドで表示
  //field.value.substr(0, start)で選択された文字列よりも前を、field.value.substr(end, field.value.length)で選択された文字列よりも後ろを取得しておく。でないとボタンをクリックした時にそれらの部分が上書きされる。
  field.value = field.value.substr(0, start) + tag[0] + target + tag[1] +field.value.substr(end, field.value.length);
  //'<b>~</b>'の部分を選択状態にする
  field.focus();
  field.setSelectionRange(start, (start + tag[0].length + selected + tag[1].length));
 });
});

```

・三項演算子
if文の省略形または代替手段として利用する。３つの値・式を必要とする特殊な演算子。
条件式 ? Trueの処理 : Falseの処理
javaのシリアライズ(Serializable)


###1.データクラスをSerializableをインプリメントする


    class Person implements Serializable {
	private String name = "Tom";
	private int age = 16;
	public Person () {

	}
	public Person(String name ,int age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", getClass()=" + getClass() + ", hashCode()=" + hashCode()
				+ ", toString()=" + super.toString() + "]";
	}
    }


###2.ファイル出力先決める

	private static String filename = String.format("D:%s99_temp%sseri", File.separator,File.separator);


###3.シリアライズする

	private static void serializable (Person person ) {
		try {
			ObjectOutputStream oOutputStream = new ObjectOutputStream(new FileOutputStream(filename));
			oOutputStream.writeObject(person);
			oOutputStream.close();
		} catch (FileNotFoundException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		} catch (IOException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		}
	}


###4.反シリアライズする、（保持ファイルをオブジェクト化する）


	private static void deserializable() {
		try {
			ObjectInputStream oInputStream = new ObjectInputStream(new FileInputStream(filename));
			Person person = (Person) oInputStream.readObject();
			System.out.println(person.toString());
			oInputStream.close();
		} catch (ClassNotFoundException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		} catch (IOException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		}
	}


###5.テストする

	public static void main(String[] args) {
		serializable(new Person());
		deserializable();
	}

※結果：Person [name=Tom, age=16, getClass()=class com.yanheng.serializable.Person, hashCode()=1607521710, toString()=com.yanheng.serializable.Person@5fd0d5ae]

###6.まとめ

| No.       |       使用クラス、インターフェース |    備考    |
|:-----------------|------------------:|:------------------:|
| 1.データクラス継承             |              Serializable |        シリアライズ        |
| 3.シリアライズ             |              ObjectOutputStream |  オブジェクトの書き出し |
| 3.シリアライズ             |              FileOutputStream|   ファイルの書き出し |
| 4.反シリアライズする             |              ObjectInputStream |   オブジェクトの読み込み |
| 4.反シリアライズする             |              FileInputStream|   ファイルの読み込み |


###[サンプルコード](https://github.com/YanHengGo/java/tree/master/09_serializable)
How to Prepare for Html Interview

HTML, CSS, JavaScript are the essential technologies for every web developer to know. S/he should also be good in both practical and theoretical knowledge of these concepts. It is because s/he needs them to explain during an interview for getting selected for the job. And s/he would need them hands-on for demonstrating in the real-time working on a project assignment.

![How to Prepare for Html Interview.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289419/b6647de8-2568-422e-96f1-cae213c51cf7.jpeg)

Here, I'm going to share some facts which could help every web developer in some way or other not only during the interviews but also at work as well. The only way to be fully prepared is to know in advance what the interviewer or hiring manager expects from you. In support of that, here are a few ideas I feel would be the key:

## Awareness of the Latest Standards

You should be acquainted with the latest HTML standards, features, and the best practices.

- What are the tags introduced in HTML5 or 5.1?
- Does the new standard talk about best practices and what are these?
- What's the right way to attach a media?
- How to handle non-standard fonts?

## Device Independent Approach for Design

It's quite essential to produce a design which is compatible with different devices of varied sizes. A good web developer should aware of good responsive design, not specifically the code-wise but also have a design-oriented approach. It is likely that the interview shall check you on how to make web pages, elements, menus, nav bars display consistently on differnt devices.

## Good Know-how of DOM/CSS Selectors

If the organization you're planning to join has a track record of making their interview process tough and regress, then they shall put up questions related to complex CSS selectors and how to use them access elements in a different scope and dynamic styling.

## Miscellaneous Facts

Another essential thing is while you are getting ready and presenting for the interview is to exhibit enough confidence in yourself. It will even make the recruiters confused what to ask.

Real confidence backed with the right skills can certainly bring success for you.

Also, you should refer to many useful resources such as the latest [HTML interview questions](https://www.techbeamers.com/latest-html-interview-questions/) available on the internet and make sure not to leave any stone unturned in entirely getting equipped with the HTML skills you need.

Wish you all the best for succeeding in your next HTML interview.
AWS Lightsailの設計図でWordPressを選択したときのphpMyAdminの設定

AWS LightsailでWordPressインストールを試してみました。数分でサイトが立ち上がりました。

![lightsail_wordpress_phpmyadmin.PNG](https://qiita-image-store.s3.amazonaws.com/0/14769/834c99e7-924a-9bed-d010-c24fa4604c7e.png)

SSHでログインしたところphpmyadminフォルダが存在していたため、ブラウザ経由で以下のURLで接続を試みましたがエラーメッセージが表示され接続できませんでした。

URL
```http://[パブリックIP]/phpmyadmin```


エラーメッセージ

```
For security reasons, this URL is only accessible using localhost (127.0.0.1) as the hostname.
```

アクセスできるように設定を変更しましょう。

## 設定方法

メッセージの通り、localhostからの接続のみ許可されているため、設定ファイルを変更します。

ファイル
```/opt/bitnami/apps/phpmyadmin/conf/httpd-app.conf```

### 設定内容

#### 固定IPアドレスを許可する場合

```
<IfVersion >= 2.3>
Require ip [許可するIPアドレスを記入]
Require local
</IfVersion>
```

#### すべての接続を許可する場合
※別途Basic認証とかかけましょう

```
<IfVersion >= 2.3>
Require all granted
</IfVersion>
```

#### IPが許可されていない場合Basic認証を表示

```
<RequireAny>
Require ip [許可するIPアドレスを記入]
AuthType basic
AuthName "Secure Zone"
AuthUserFile [/path/to/.htpasswd]
Require valid-user
</RequireAny>
```

設定変更後、以下のコマンドでApacheを再起動します。

```sudo /opt/bitnami/ctlscript.sh restart apache```

※graceful, reload系のオプションは用意されていませんでした。

```
bitnami@ip-172-26-9-155:~$ sudo /opt/bitnami/ctlscript.sh
usage: /opt/bitnami/ctlscript.sh help
       /opt/bitnami/ctlscript.sh (start|stop|restart|status)
       /opt/bitnami/ctlscript.sh (start|stop|restart|status) mysql
       /opt/bitnami/ctlscript.sh (start|stop|restart|status) php-fpm
       /opt/bitnami/ctlscript.sh (start|stop|restart|status) apache

help       - this screen
start      - start the service(s)
stop       - stop  the service(s)
restart    - restart or start the service(s)
status     - show the status of the service(s)
```

![lightsail_wordpress_phpmyadmin2.PNG](https://qiita-image-store.s3.amazonaws.com/0/14769/e3e13025-086b-4ce7-740d-21dec5970f2c.png)

見れました！

デフォルトのユーザー名は```root```、ログインパスワードは以下のファイルに記載してあります
```cat /home/bitnami/bitnami_application_password```
Vue.js と WordPress の 付き合い方について考えてみた

WordPressと長く付き合ってきて、最近はVue.jsが好きという方 多いと思います。（私です)

WordPress と Vue.js はどのような関係で付き合うのか良いか？
そもそも付き合えるのか？について週末 悶々といろいろ試していました。という日記です。

# ２つの方向性を考えてみた

**1. WordPress REST API + Nuxt.js (SSR) 方向** 
**2. php + Vue.js で超シンプルな 脱jQuery的 お付き合い**

## バックとフロントの分離

稼働中WordPressメディアのリニューアル等の際に、そのままバックエンドとして分離、隠してしまって、
フロントからAPIで取得する、というようなストーリーを想定。

モダンjsフレームワークでメディアというと、JAM Stack思想のもと、contentfulのようなヘッドレスcmsと、SSG。
Netlifyに置き、「爆速！素敵！PWAも行っちゃう？」 のようなひとつ理想郷と思います。

コーポレートサイト等、ニュースだけ用CMS のような小規模用途であれば、この方法は良さそうですが、
ブログ、メディア的な場合には、ライター複数人が管理画面に参加するため、SSGでの運用は現実的に思えない。

個人的に仕事として、メディアとしての用途が多いため、
Nuxt.js のSSRでブログメディア的なものをとりあえず hello world してみます。

# 1. WordPress REST API + Nuxt.js (SSR) 方向

今回はありものだけで簡単にトライします。

## 前提
・npm , vue-cli , heroku cli などの依存パッケージはインストール済み。
・データの入ったwordpressサイトを一つ用意する。(なんでもよい)

※ コードは端折ります。

## nuxtのプロジェクトを用意

同じようなコンセプトのリポジトリがいくつかありました。 4つほど試して、今回はこちらが良さそうでした。

https://github.com/krestaino/nuepress 

肝心のAPI連携部分は [store/index.js](https://github.com/krestaino/nuepress/blob/f03511adedaf5f2b475577ae6a0fa57022fb35ae/store/index.js#L31) にかかれていました。
`state.wordpressAPI` の値を自分のサイトへ変更して、 axiosで REST APIを叩き、Nuxtで展開する形です。

`$ npm run dev` で  ＼(^o^)／ できたー。

SSRは無料のheroku等へ。モダンなブログがサクッと誕生しました。


## 実際には

シングルポストタイプの超単純なブログであれば、上記をちょっと改造して「完成あっぱれ！」ですが、実際のWordPressでは、そのサイト毎異なるデータをあつかっており、事情もまちまち。

- カスタムフィールド / カスタムポストタイプ / カスタムタクソノミー
- ウィジェット / メニュー
- テーマオプション
- Contact Form 7
- seo系プラグイン
- 人気記事・ランキング
- 認証方法
- 著者の権限

　　　　　　　…などなど

特にブログメディアの場合は「seo命」。パーマリンク設定や metaタグ類も超シビアです。

## 大変じゃね？

WordPress REST API は、どうにも非常に細かい事情を加味するにはガッツリ受け側で工夫が必要そうというのが今の印象です。

WordPress側で、カスタムエンドポイントを自作したり、プラグインによっては REST API サポートの追加プラグインを出していたりするが、まちまち。全て個別に調べる必要がありそうです。
やるとなると、相当の覚悟と体力をもって臨まないと、できなそうということは解りました。

そしてサーバー費用は倍 (か それ以上?)。

なんか本当にこれをやる必要があるのかで、心が一回くじけました。
すでに完成しているwordpressを再発明してまで、受けたいvueの恩恵とは？ ...判断ミス感すごい。
もう少し体力があるときに、続きをトライしてみます。 orz

# 2. php + Vue.js で超シンプルな 脱jQuery的 お付き合い

wordpressからデータを取るのではなく、あくまでレンダリングはphpにまかせ、webpackから css と js を `/wp-content/theme` に吐き出してあげるだけ。そうそう、ちょこっと使えるのが、Vueの魅力。

「当然 vuex , vue-router とかも使わない感じじゃね」
「SFCは使ってもよさそうだけど、なんかソースの散らばり方が気持ち悪い。コンポーネントいらなくね？」
「となるとWebpackいらなくね？ cdnでよくね？」
「むしろjsあんま書かなくね？」
「…………  jQueryでよくね？」 |дﾟ)ﾁﾗｯ

無論サイトの目的にもよりますが。ブログユースではこんな印象です。

# 結論

相当な覚悟でガチらない限りは、いらない感がすごい。。
やはり、アプリ は アプリ、wordpress は wordpress と割り切るのが幸せかもしれない。


「こうやるといい感じだよ」
「私はこうやったよ」 等 
ご意見いただけると嬉しいです。読んで頂きありがとうございます。
Goのfor文で複数の変数を同時に回す

例えばC言語だと、iとjの2つの変数を操作しながらfor文を回すことができた。

```c
#include <stdio.h>

int main(void) {
	int i, j;
	for (i = j = 0; i < 10 && j < 10; i++, j++) {
		printf("%d, %d\n", i, j);
	}
}
```

一方、Goのfor文は同じことができない。いくつか制限があるからだ。

* 連続代入ができない。
* assignment statementはstatementであって式ではない。
* forのセミコロンの前(InitStmt)と最後(PostStmt)に書けるのはSimpleStmtだけであり、複数の文を書けない。

というわけで、複数代入を工夫をするとここまでできるけど、

```go
package main

import "fmt"

func main() {
	for i, j := 0, 0; i < 10 && j < 10; i, j = i+1, j+1 {
		fmt.Println(i, j)
	}
}
```

この場合、`i++`や`j++`は使えなかった。

複雑なことがしたかったら、forの前やforの中に書けばよい、という思想なのかもね。

ちなみにif文だと条件式の手前に別の文を置けるけど、、、

```go
if err := doSomething(); err != nil {
  //...
}
```

実はこれはif文の特殊機能だった。あらゆる場所で使える機能ではない。
https://golang.org/ref/spec#If_statements
Project Euler 問題3 「600851475143の最大の素因数」

## 問題
600851475143　の最大の素因数を求めよ。

>The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?

## コード
```python
def divideByFactor(factor, num):
  while(num % factor == 0): #割り切れなくなるまで割る
    num /= factor
  return factor, num
  
num = 600851475143
factor =1

while num >= factor:
  factor += 1
  factor, num = divideByFactor(factor,　num)

print(factor)
```
AndroidのGoogle Maps API v2 キーの取得方法

久々にMap APIキーを取ろうとしたら完全に忘れていたので記録。

GoogleAPIコンソールからも作成できるが、**Android Studioから作ったほうが楽**

# 前提
- Googleアカウントがありブラウザでログイン済み
- Android Studioインストール済み

# 手順
1. Android StudioでMapsActivityを作成
- APIキー作成のURLに遷移
- GoogleAPIコンソールでAPIキーを作成
- Android Studioでキーを貼り付け

# 1.Android StudioでMapsActivityを作成

### MapsActivityを作成する理由
Android StudioでMapsActivityを作成することで、**APIキーを簡単に作成するURLが自動生成される。**

ではさっそく作成していく

Google Maps Activity を選択

![Android StudioでMapsActivityを作成.png](https://qiita-image-store.s3.amazonaws.com/0/52227/5fcc3c6a-b17a-8a1e-c40d-21dc7840b04e.png)

そのままFinishを押す

<img width="912" alt="スクリーンショット 2018-11-10 16.13.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/52227/6acb751e-6162-7390-52e7-74cd2c81f826.png">

`google_maps_api.xml` が作成され、以下スクショのような文字列が作成されていればOK

<img width="1440" alt="スクリーンショット 2018-11-10 16.14.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/52227/39199dac-0ade-8275-8ab2-9ae6162e4cf3.png">

# 2.APIキー作成のURLに遷移

`google_maps_api.xml` の矢印のURLをブラウザに貼り付けて遷移する

<img width="1440" alt="スクリーンショット 2018-11-10 16.14.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/52227/67277628-fcca-a216-ea7c-ed93987b4aef.png">


# 3.GoogleAPIコンソールでAPIキーを作成

`プロジェクトを作成` のまま **続行** を押す

<img width="566" alt="スクリーンショット 2018-11-10 16.16.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/52227/3d526378-1f9b-d719-da4c-dfb50d0bafa2.png">

`API キーを作成する` を押す

<img width="514" alt="スクリーンショット 2018-11-10 16.17.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/52227/d5aefd4b-2060-16d4-e642-cb62edf0c33c.png">

作成されたAPIキーを確認

<img width="1371" alt="スクリーンショット 2018-11-10 16.18.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/52227/82047a68-7f3b-9ed8-5789-a26c77fa95c7.png">


# 4.Android Studioでキーを貼り付け

Android Studioに戻り、`google_maps_api.xml` にAPIキーを貼り付ける。

<img width="1440" alt="スクリーンショット 2018-11-10 16.14.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/52227/a847d0b8-bee6-8d1d-d180-3225069dc73b.png">

あとはビルドするとGoogleMapが表示されて完了
Django x Python x Dockerを使って開発する環境構築準備

この記事は、Djangoを使って簡単なWebアプリケーションの手順を記載して記事になります。
https://docs.djangoproject.com/ja/2.0/intro/tutorial01/
を参考に導入まで行ってみます。

### ■ 動作検証
**docker pull centos**

```
# cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core) 
```

### ■ 事前準備(各インストール)

**Python**

```
$ yum install -y sudo
$ sudo yum install -y https://centos7.iuscommunity.org/ius-release.rpm
$ sudo yum search python36
$ sudo yum install python36u python36u-libs python36u-devel python36u-pip
$ python3.6 --version
Python 3.6.5
```

**pip**

```
$ curl -kL https://bootstrap.pypa.io/get-pip.py | python3.6
$ pip -V
pip 18.1 from /usr/lib/python3.6/site-packages/pip (python 3.6)
```

**Django**

```
$ pip install Django
$ python3.6 -m django --versio
```

### ■ プロジェクト作成

プロジェクト作成

```
$ django-admin startproject mysite
$ ls -la mysite/
total 16
drwxr-xr-x 3 root root 4096 Nov 11 05:21 .
drwxr-xr-x 3 root root 4096 Nov 11 05:21 ..
-rwxr-xr-x 1 root root  538 Nov 11 05:21 manage.py
drwxr-xr-x 2 root root 4096 Nov 11 05:21 mysite
```

サーバ起動

```
$ python3.6 manage.py runserver
Performing system checks...

System check identified no issues (0 silenced).

You have 15 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.

November 11, 2018 - 05:25:22
Django version 2.1.3, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

...
```

これで開発できる準備が整いました。

アプリケーションを作っていきます。今回は、poolsです。

```
$ python3.6 manage.py startapp polls
$ tree polls/
polls/
|-- __init__.py
|-- admin.py
|-- apps.py
|-- migrations
|   `-- __init__.py
|-- models.py
|-- tests.py
`-- views.py
```


正しく、起動しているかビューを作成して確認してみます。
以下のファイルを記載していきます。


```python:polls/views.py
from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello World")
```

次にアプリケーションディレクトリ配下に『urls.py』を作成していきます。

```python:polls/urls.py
from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='index'),
]
```

最後に作成したビューをURLと紐づけていきます。

```python:mysite/urls.py
from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('polls/', include('polls.urls')),
    path('admin/', admin.site.urls),
]
```

ここまでで、`$python3.6 manage.py runserver`でサーバを起動した状態で
http://localhost:8000/polls/ へアクセスして『Hello World』が出てきたらOKです。
Electron vueでbuild時にUnexpected tokenが出る

```
ERROR in unknown: Unexpected token (14946:4)
Child html-webpack-plugin for "index.html":
     1 asset
    Entrypoint undefined = index.html
    [0] ./node_modules/html-webpack-plugin/lib/loader.js!./src/index.ejs 1.28 KiB {0} [built]
    [1] ./node_modules/lodash/lodash.js 527 KiB {0} [built]
    [2] (webpack)/buildin/module.js 497 bytes {0} [built]
```

packしてもbuildしても出る。

原因はvue内でjsしか書いてないのにts宣言している箇所があることだった・・・

```
<script lang="ts">
```

しょうもない時間を潰してしまった・・・
AmplifyとReactを使用して爆速でWEBアプリを作成する

##Amplify Command Line Interface (CLI)のインストール
初めてAmplifyを使う場合には以下のコマンドを実行する。

```
npm install -g @aws-amplify/cli
amplify configure
```
Enterを押していくと、IAM Management Consoleが開くので、
ブラウザ上でIAMロールを作成して、accessKeyIdとsecretAccessKeyを取得する。

##create-react-appでアプリケーション作成
```
npm install -g create-react-app
create-react-app myapp && cd myapp
npm start
```

##Amplifyのインストール
```
npm install --save aws-amplify
npm install --save aws-amplify-react
```

##Amplifyの設定
```
amplify init
```
以下のような感じ(?)
? Choose your default editor: Emacs (via Terminal, Mac OS only)
? Choose the type of app that you're building javascript
Please tell us about your project
? What javascript framework are you using react
? Source Directory Path:  src
? Distribution Directory Path: build
? Build Command:  npm run-script build
? Start Command: npm run-script start

##公開
```
amplify add hosting
amplify publish
```
AssumeRole を利用した Redshift から S3 へのクロスアカウントアクセス

# 目的
Redshift から他アカウントの S3 に AssumeRole を使ってアクセスする方法が意外とややこしかったので整理する。

# 想定状況
２つのアカウントを持っていて、 Account A (accountID:111111111111) には Redshift があり、 Account B (accountID:222222222222) に存在する S3 にアクセスする必要がある。
このアクセス方法はいくつかあるが、今回は AssumeRole による一時認証を使う方法を採用する。

# 手順の概要
1. Account A で Redshift 割り当て用のロール(AccountA-Redshift-Role)を作成する
2. Account B で AccountA-Redshift-Role に対して S3 アクセスを信頼する Role(accountB-S3-Assume-Role) を作成する
3. Account A の Redshift 用のロールに accountB-S3-Assume-Role を引き受けるポリシーを追加する
4. Account A の Redshift に AccountA-Redshift-Role を割り当て、 Account B の S3 へアクセスする

1~3 は通常のクロスアカウント設定で難しい点はないが、 4 でのアクセス方法が意外とややこしい

# Redshift から他アカウントの S3 にアクセスする
## IAM の設定
### Account B
Account A へ権限を委譲するための accountB-S3-Assume-Role という名称の IAM ロールを一つ作成する。
これには下記２つのポリシーが含まれている

* s3 バケット s3://bucket.accountB 配下へのアクセス許可
* Account A の IAM Role への信頼

#### s3 へのアクセス許可ポリシー
```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Sid",
            "Action": [
                "s3:ListBucket"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::bucket.accountB"
        },
        {
            "Sid": "Sid",
            "Action": [
                "s3:GetObject"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::bucket.accountB/*"
        }
    ]
}
```

#### AccountA の IAM Role に対する信頼ポリシー
```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Sid",
            "Effect": "Allow",
            "Principal": {
            "AWS": "arn:aws:iam::111111111111:role/AccountA-Redshift-Role"
        },
        "Action": "sts:AssumeRole"
        }
    ]
}
```

### Account A
account B で作成したロールを引き受けるポリシーを Redshift に割り当てる IAM ロールに追加する
#### AccountA の権限を引き受けるポリシー
```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Sid",
            "Action": [
                "sts:AssumeRole"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:iam::222222222222:role/accountB-S3-Assume-Role"
        }
    ]
}
``` 

## Redshift の S3 アクセス処理
まず、Redshift の IAM ロールに AccountA-Redshift-Role を付与する。
下記2点の方法で Redshift から S3 へのクロスアカウントのアクセス処理を行う。

* Redshift による copy コマンドを使った S3 上ファイルのロード
* Redshift Spectrum を使った S3 に対する外部スキーマ作成

### Redshift Copy
AssumeRole を利用したクロスアカウントの copy コマンドは下記のようになる。
`iam_role` 以下に copy 時に必要な IAM ロールの ARN を設定する。
この際にクロスアカウントの場合、カンマ区切りで権限引き受け元の IAM Role を指定する必要がある。
これを<b>ロールの連鎖（ロールチェーン）</b>と呼ぶらしい。

```sql
copy 's3://bucket.accountB/' 
iam_role 'arn:aws:iam::111111111111:role/AccountA-Redshift-Role,arn:aws:iam::222222222222:role/accountB-S3-Assume-Role'
;
```
### Redshift Spectrum
Redshift Spectrum を使ったクロスアカウントの場合も同様に、ロールの連鎖で iam_role を使って外部スキーマを設定する必要がある。

```sql
create external schema test from data catalog 
database 'test' region 'ap-northeast-1' 
iam_role 'arn:aws:iam::111111111111:role/AccountA-Redshift-Role,arn:aws:iam::222222222222:role/accountB-S3-Assume-Role'
;
```

# おわりに
AssumeRole で権限委譲元アカウントの IAM ロールの ARN を指定する必要があるとは思わず、手間取ってしまった。
なぜこの指定が必要なのかをまだ理解できていないのが残念だが、これで AssumeRole を利用した Redshift のクロスアカウントアクセスが可能になる。