OmniAICreator/Qiita-1.07M huggingface dataset:
やってみようReact Native！ By Globis

#やってみようReact Native！
##第1部:React Nativeとは何か
***フレームワーク***です!!

###**メリット**
1. React Native = フレームワーク
  - １つのコードベースでAndroidをiOSのネイティブアプリ開発を行える、Reactをもとにしたフレームワーク。
2. Reactの思想を受け継ぐ
  - 「Learn once, write anywhere」一度覚えたら何にでも書ける。
  - 仮装DOMを用いれば大抵のUIを表現できる。
  - Reactではブラウザがレンダラ、React NativeではネイティブUIがレンダラ。
  - Reactを学んだことをReact Nativeに応用することができる。
3. 効率の良い学習ができる
  - React Nativeではネイティブ側への変更が加わらない場合はネイティブのコンパイルはされない。
  - ソースコードを書いてから実行されるまでの時間が短い。
4. ECMAScript2015での開発
  - npmの豊富なライブラリを使用でき、UIライブラリもたくさんあるため開発コストが低い
  - 静的型チェックが可能(Flowを使うことで実現可能)
5. リリース後でもソースコードを変更可能
  - アプリのリリースサイクルが遅くなる原因の一つがリリース前に入念なアプリ品質チェックを行うこと。
  - UIへの反映やロジックの実行など、ほとんどの実装はJSのソースコードで行なっているため、アプリ自体をストア経由でアップデートせずにJSのソースコード差し替える事でリリース後のソースコード更新も容易。

###**デメリット**
1. パフォーマンス
  - UIの構築で実装方法によってはパフォーマンスが悪くなる。(Androidでは特に)

2. AndroidとiOSの知識が必要
  - アプリのコンパイル、ビルド、設定周りは固有の知識が必要。

3. 標準的なUIがない
  - 各OSでは標準的なUIのガイドラインやそれを実装するライブラリがあるがReact Nativeには存在しない。

4. 未対応のライブラリ
  - AppleやGoogleが発表したばかりの機能はReact Native用のライブラリが存在せず対応に時間がかかる。



##第2部:開発環境構築
- インストールするもの
  - Android Studio
  - Xcode
  - Node.js実行環境

###1. Node.js
1. Node.jsのインストール(NodebrewでもHomebrewでもanyenvでも何でもOK)
  - npmコマンド、nodeコマンドが実行できるか確認
  
      ```bash
node -v
npm -v
```

2. React Nativeのコマンドラインツールのインストール

```bash
npm install -g react-native-cli
```

###2. Android
1. Android Studioをインストール
2. Android SDK 6.0をインストール(Android Studio起動画面から)<img width="774" alt="スクリーンショット 2018-04-02 13.45.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/59015/671399da-608f-80b8-1640-617a6841eb6b.png">
3. Android SDK Build-Toolsの23.0.1をインストール(Android Studio起動画面から)
4. 環境変数の設定

    ```bash
export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/platform-tools
```

5. 仮想デバイスを用意する(Android Studio)
<img width="997" alt="スクリーンショット 2018-04-02 13.52.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/59015/f978a112-228f-6e9b-b377-6f5a31c4f42a.png">

###3. iOS
  1.  App Storeからインストール

以上で実行環境の構築終了
「Android Studio」と「Xcode」のインストールに時間がかかりますが簡単に構築できます。
Androidの構築が今後もう少し改善されることに期待しています。


##第3部:サンプルアプリ作成
###No.1 Hello World
1. アプリの雛形の作成

    ```bash
react-native init ProjectName #ProjectNameにはプロジェクト名をお好みで指定してください
```

2. iOSシミュレータで実行

    ```bash
react-native run-ios
```

3. Androidエミュレータで実行
＊Android Studioでエミュレータを起動させておく
*iOSシミュレータ起動時にアプリと通信するReact Native用のサーバーが別ターミナルで起動しているのでそれを停止させる(Ctrl + c)

    ```bash
react-native run-android
```

###No.2 npmライブラリを使う
[React Nativeでnpmライブラリを使う](https://qiita.com/takehiro224/items/d60243820b069197e4ba)
React Nativeではライブラリの管理にnpmを利用しています。
npmを利用することで、ライブラリの管理からコマンドの実行まで、様々なことを行えます。
ここではnpmを利用する手順や注意などを動かしながら試して行きます。


###No.3 Flowによる静的型チェック
[Flowによる静的型チェック](https://qiita.com/takehiro224/private/01b3851ffe71482ac655)
JavaScriptは静的型付き言語ではなく変数に様々なデータを格納できますが、思わぬ型を変数に代入してしまいエラーを起こす危険があります。そこで使うと便利なものが**Flow**です。

###No.4 jestによるテスト(編集中...)
React NativeでのテストではFacebook製のテスティングフレームワークであるjestを標準で利用できます。
jestは標準的なアサーションや非同期処理テストのサポート、importやrequireで呼び出すライブラリまでモック化できる強力なモックライブラリです。




続く...
[test020] テーブル横ソート

# テーブル横ソート

## 仕様
tbodyの1列目をクリックすると、右側の表を横方向にソートする

## ソース

### javascript
```javascript:test020.js
$(function(){
  $('#t1 tbody td').filter(function(){
    return $(this).closest('tr').find('td').index(this)==0;
  }).on('click',function(){
    var list=$(this).siblings('td').map(function(x){return {idx:x+1,num:parseInt($(this).text())}}).get();
    list.sort(function(x,y){
      if(x["num"]==y["num"]) return 0;
      return x["num"]>y["num"]?1:-1;
    });
    $(this).closest('table').find('tr').each(function(){
      var self=$(this);
      list.forEach(function(x){
        self.find('td,th').eq(x["idx"]).clone().appendTo(self);
      });
      self.find('td,th').filter(':gt(0):lt('+list.length+')').remove();
    });
  });
});

```
### HTML
```HTML:test020.htm
<html>
<head>
<title>テーブル横ソート</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script type="text/javascript" src="test020.js"></script>
</head>
<body>
<h1>テーブル横ソート</h1>
<h2>tbodyの1列目をクリックすると、右側の表を横方向にソートする</h2>
<table id="t1">
<thead>
<tr>
<th data-type="string">名前<span></span></th>
<th data-type="integer">国語<span></span></th>
<th data-type="integer">数学<span></span></th>
<th data-type="integer">保健<span></span></th>
<th data-type="integer">社会<span></span></th>
<th data-type="integer">美術<span></span></th>
<th data-type="integer">英語<span></span></th>
</tr>
</thead>
<tbody>
<tbody>
<tr class="dothesort">
<td>鈴木</td><td>12</td><td>19</td><td>25</td><td>25</td><td>89</td><td>25</td>
</tr>
<tr class="dothesort">
<td>高橋</td><td>25</td><td>89</td><td>25</td><td>25</td><td>89</td><td>25</td></tr>
</tr>
<tr class="dothesort">
<td>佐藤</td><td>60</td><td>987</td><td>89</td><td>25</td><td>89</td><td>25</td>
</tr>
<tr class="dothesort">
<td>山田</td><td>604</td><td>78</td><td>25</td><td>25</td><td>89</td><td>25</td>
</tr>
</tbody>
</table>
</body>
</html>
```

## その他

### サンプル
-[CodePen](https://codepen.io/yambejp/pen/wmjbWp)

<p data-height="400" data-theme-id="0" data-slug-hash="wmjbWp" data-default-tab="html,result" data-user="yambejp" data-embed-version="2" data-pen-title="test020" class="codepen">See the Pen <a href="https://codepen.io/yambejp/pen/wmjbWp/">test020</a> by yambe jp (<a href="https://codepen.io/yambejp">@yambejp</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
SymbolOperator (MongoMapper 由来)

`Model.where(:id.ne => nil)` などと書けるやつ。 MongoMapper の独自拡張で、 mongo-ruby-driver 直で使う場合は通らない。

```ruby
[3] pry(main)> :id.ne
#<SymbolOperator:0x00007fb64e33a660 @field=:id, @operator="ne">
[4] pry(main)> :id.ne.class
SymbolOperator < Object
[5] pry(main)> :id.ne.class.ancestors
[
    [0] SymbolOperator < Object,
    [1] Comparable,
    [2] Object < BasicObject,
    [3] ActiveSupport::Dependencies::Loadable,
    [4] PP::ObjectMixin,
    [5] MongoMapper::Extensions::Object,
    [6] JSON::Ext::Generator::GeneratorMethods::Object,
    [7] Kernel,
    [8] BasicObject
]
```

ってなってるけど、 SymbolOperator が定義されてるのは Plucky gem のほう https://github.com/mongomapper/plucky/blob/master/lib/plucky/extensions/symbol.rb

Symbol に `.ne` メソッドなどをはやしていて、そのメソッドの返り値が SymbolOperator のインスタンス。という具合。

ショートハンドで書けて便利かと思いきや、 mongo-ruby-driver 直で使いたい場合の書き換えでミスりやすいので、 `.where(:id => { '$ne' => nil })` みたいに書くようにしたほうがよさそう。
What do you like the most about DevOps, how to be great at it & is there anything you dislike about DevOps?

Someone asked me, 'What do you like the most about DevOps, how to be great at it & is there anything you dislike about DevOps?' 

This was my reply,

DevOps is a cultural phenomenon in any organization. It is more related to automation (writing scripts to automate) of different tasks that otherwise take a lot of time and prone to error if done manually.

Every company today, regardless of industry, is under pressure to be great at developing and delivering software. This is because the software is disrupting every type of business, from taxi services to food delivery to retail. Unless you transform your business and go through a digital transformation, your business is likely to die in the next few years.

a DevOps engineer can be a developer who can think of an Operations mindset and has the following skillset:

> Familiarity and experience with a variety of Ops and Automation tools

> Great at writing scripts

> Comfortable with dealing with frequent testing and incremental releases

> Understanding of Ops challenges and how they can be addressed during design and development

> Soft skills for better collaboration across the team

DevOps is recently taking the center stage in the software industry, and hence there is nothing much to dislike about it.

We also have written an in-depth article on the same. 

[How to be a Great DevOps Engineer](http://bit.ly/greatdevops)

What is your take on this.
Google Cloud PackagesのGPGでエラー。2018/04/02

# 概要
```
% sudo apt-get update
...略

W: 署名照合中にエラーが発生しました。リポジトリは更新されず、過去のインデックスファイルが使われます。GPG エラー: https://packages.cloud.google.com/apt cloud-sdk-xenial InRelease: 以下の署名が無効です: KEYEXPIRED 1522631986
W: https://packages.cloud.google.com/apt/dists/cloud-sdk-xenial/InRelease の取得に失敗しました  以下の署名が無効です: KEYEXPIRED 1522631986
W: いくつかのインデックスファイルのダウンロードに失敗しました。これらは無視されるか、古いものが代わりに使われます。
...略
```

`apt-get update` でエラーが出るので対応する

# 確認
```
% apt-key list | egrep -B1 -i 'google cloud'                                
pub   2048R/A7317B0F 2015-04-03 [期限切れ: 2018-04-02]
uid                  Google Cloud Packages Automatic Signing Key <gc-team@google.com>
```

エラーの通り期限切れ

# 対応
```
% curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1326  100  1326    0     0   7679      0 --:--:-- --:--:-- --:--:--  7709
OK
```

**確認**

```
% apt-key list | egrep -B1 -i 'google cloud'                                
pub   2048R/A7317B0F 2015-04-03 [期限切れ: 2018-04-02]
uid                  Google Cloud Packages Automatic Signing Key <gc-team@google.com>
--
pub   2048R/BA07F4FB 2018-04-01 [有効期限: 2021-03-31]
uid                  Google Cloud Packages Automatic Signing Key <gc-team@google.com>
```

追加された

# まとめ
`apt-key add` で解決してよかった。
DotinatallのHeroku講座でハマったとこ記録

# お題
ドットインストール先生の力を借りてHerokuを学び始めました。
思いの外、色々ハマったので、その記録を残していきます。
# 必要な知識
HerokuサーバーにアップするアプリはRailsで用意するし、そのアプリを動かしたり、HerokuにアクセスするのはCentOSからする。また、そのCentOSの仮想環境の用意にはVagrantが必要と、かなり前知識がいる。
- Ruby and Rails
- Vagrant
- PostgreSQL
# ハマったとこ
その中で、自分がハマったところだけピックアップして説明したいと思います。
## Ruby, Railsのインストール
CentOSだし、yumでインストールしようとすると古いバージョンになってしまい、Railsが使えない。
ちゃんとパッケージのインストールからして、新しいバージョンのRubyのインストールが必要。
こちらを参考にさせていただきました。
https://qiita.com/iamdaisuke/items/46da26b4060ddec18895
## Heroku CLI(Herokuコマンドラインインターフェイス)
別にハマった記憶はないけど、メモが残ってたので…

```
wget https://cli-assets.heroku.com/branches/stable/heroku-linux-amd64.tar.gz -O heroku.tar.gz
mkdir -p /usr/local/lib
sudo tar -xvzf heroku.tar.gz -C /usr/local/lib
sudo /usr/local/lib/heroku/install
```
## SSH Key(公開鍵、認証鍵)の設定
ドットインストールだと最初っからSSH Keyあるけど、自分のではなかった…
適当に用意したCentOSにはありませんでした。
というわけで、下記コマンドで作成。

```
ssh-keygen -t rsa -b 4096
```
下記コマンドで、確認できます。

```
cd .ssh
ls
```
## SSH Key設定後のVagrant up
さて、SSH Keyを用意した後、CentOSを再起動（Vagrant up）。
必要だったからというわけでなく、次の日に続きをしたから。
すると、なぜかCentOSが正しく起動されない…
原因は鍵の不一致だそうで、
まずは、下記コマンドでIdentityFileをチェック。

```
vagrant ssh-config
```
ファイル場所を先ほどチェックしたIdentityFileの場所にして、下記コマンドを実行。

```
ssh-keygen -yf /Users/****/private_key > public_key
```
これで、Vagrant upできました。

こちらを参考にさせていただきました。
https://qiita.com/d2cdot-mmori/items/1c340f175ae510e4456a
## PpstgreSQLのインストール、初期設定
手順通り実施していき、Railsアプリもアップできた、Migrateしてデータベースを用意…としたいが、なんかMigrateが成功しない。
私の場合は、そもそもPostgreSQLのインストールをしていませんでした。（恥ずかしながら）
というわけで、PostgreSQLのインストールと初期設定について

```
yum list | grep postgresql-server   // Check yum. Don't use it due to old

sudo yum install -y https://yum.postgresql.org/9.6/redhat/rhel-7-x86_64/pgdg-redhat96-9.6-3.noarch.rpm
sudo yum install -y postgresql96-server postgresql96-contrib
``` 
インストール、初期設定、こちらを参考にさせて頂きました。
https://qiita.com/uhooi/items/44ed9370740c7521dce4
## Rails更新後のHerokuアップデート
作業を進めているとミスしたり、トライ＆エラーするもの。
GemfileとかProcfile間違えた、修正して再確認だ。とかしてもなぜか修正が反映されない。
なぜ…と悩んでみるが原因はシンプルで、修正後はもう一度bundle installしてからGit pushしないと反映されません。

```
bundle install
git add .
git commit -m "comment"
git push heroku master
```
Railsの仕様なんですかね。Railsせずに来たのでわかりません。
# 最後に
必要になる知識をちゃんと事前に勉強していれば、ハマったりしないと思います。
しかしながら、皆自分の環境でアプリをつくったりしているはず。
（自分の場合、Cakephp。CentOSやVagrantはわかるけど、Railsはさっぱりだった。解決策がはっきりしてないから書いてないけど、RailsのPostgreアドオン？を入れるのはめっちゃハマった。）
それをデプロイしたい、そうだHerokuを使おうと、ドットインストール講座にやってくるとハマると思ったので、記事にしてみました。
次に通る人のために、路を整えよ。
python で podcast をダウンロードした

突然ですが、

# SUNTORY SATURDAY WAITING BAR AVANTI って知ってます？

10年前位に終わってしまった FM ラジオの番組ですが、私はこれが、 **大好き**です
https://www.tfm.co.jp/podcasts/avanti/

ポッドキャストがまだ残っているようなので python で 全て取得しました

```python:qiita.rb
import urllib.request

BaseUrl = "http://podcasts.tfm.co.jp/podcasts/tokyo/avanti/"
for i in range(365):
    mp3 = "avanti_vol{0}".format(i + 1) + ".mp3"
    url = BaseUrl + mp3 
    
    print(mp3)
    print(url)
    
    urllib.request.urlretrieve(url, "C:/Users/name/Downloads/"+mp3) 
```
AndroidでManagerClassにLifecycleのイベントを渡す


こんにちは。m_saekiです。

ManagerClassとかでLifecycleのイベント渡したいときってありますよね？
そんな時はinterfaceで返せばOKです。

もっといい書き方はありそうなので、こうした方がいいよっていうのは是非ご教授お願いしますmm

## 1. LifecycleListener
``` LifecycleListener.interface
public interface LifeCycleListener {
    void create();
    void resume();
    void pause();
    void destory();
}
```

## 2. MainActivity
LifecycleListenerをセット

``` MainActivity.class
public class MainActivity extends AppCompatActivity {

	private LifeCycleListener lifeCycleListener;
	private Manager manager;

	@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        manager = new Manager(this);
        if (lifeCycleListener != null) lifeCycleListener.create();
        // ... proc
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (lifeCycleListener != null) lifeCycleListener.resume();
        // ... proc        
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (lifeCycleListener != null) lifeCycleListener.pause();
        // ... proc
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (lifeCycleListener != null) lifeCycleListener.destory();
        // ... proc        
    }
    
    public void setLifeCycleListener(@NonNull final LifeCycleListener lifeCycleListener) {
        this.lifeCycleListener = lifeCycleListener;
    }
}
```

## 3. Manager

``` Manager.class
public class Manager implements LifeCycleListener {

	public Manager(MainActivity activity) {
		activity.setLifeCycleListener(this);
	}

	@Override
    public void create() {
	    // ... proc
    }

    @Override
    public void resume() {
	    // ... proc    
    }

    @Override
    public void pause() {
	    // ... proc    
    }

    @Override
    public void destory() {
	    // ... proc    
    }
}
```

## 4. 終わりに
以上でManager.classにMaingActivityのLifecycleEventを受け取るように実装できます。
参考までに使ってもらえれば幸いです。
html章

#html章

##3章のまとめ
* レイアウトを考えるときは大枠から考えていく
* 枠を作るときは色を付けて確認しながら進める
* heightやwidthを指定するときは子要素の合計値より小さくならないように気をつける
* 横並びをするときはfloatを使う
* floatを使った時は弊害に注意する
* ボックスモデル

##4章のまとめ
* ヘッダーの作成には`<header>`タグを`<nav>` タグはナビメニューのレイアウトで使用する
* `<ul>`タグと`<ol>`タグは、子要素に`<li>`タグを持つ
* `<li>` タグは親要素が`<ul>`タグの場合、文頭が「・」、`<ol>`タグの場合、番号になる
* テキストの行揃えはtext-alignプロパティを使用する
* HTML要素にはブロックレベル要素とインライン要素があり、それぞれ特徴と使用時のルールがある
* フッターの作成には `<footer>` タグを使用する

##５章のまとめ
* background-imageプロパティを使用する際には、background-sizeプロパティや background-positionプロパティなどのプロパティも必要となる場合が多い
*　文章に改行を入れる際には`<br>`タグを入れる

##6章のまとめ
* line-heightプロパティは文字の行の高さを決めるプロパティである。
* borderプロパティは枠線の太さ、種類、色を決めるプロパティである。
* `<span>`タグは`<div>`タグのインライン要素版で、`<p>`タグの文章の特定の部分を変更する場合などによく使用する。
* `<section>`タグは、子要素に`<h>`タグを含む箱であり、`<div>`タグとの使い分けが重要である。

##7章のまとめ
* class属性、id属性は1つの要素に複数属性値を持つことができ、属性の共存も可能である。
* 特定の場合のみにCSSを適用させる「擬似クラス」が存在している

##8章のまとめ
* Font Awesome は様々なアイコンが使えるため、使える時には活用するといい。
* positionプロパティは要素の自由に位置を調整できる。
* 文字フォントはfont-familyプロパティで変更できる。
表示高速化にPageSpeed Moduleを使ったら、13秒かかるページが5秒で表示されるようになった

ちょっと前にロフトワーク社で開催された表示高速化イベントに参加してきました。その名も「CMSプロレス」。参加した際に設定したGoogle PageSpeed Moduleについて、どんな設定をしたのか書いていきます。

- [「表示最速王」の栄冠は誰の手に？ CMSバトルイベント 第3回CMSプロレス](http://www.awrd.com/projects/cmsprowrestling01/)

なお、導入は超簡単、効果は抜群なので、表示高速化を考えている方はぜひぜひ入れちゃってください。ローカルでgulpなどのタスクランナーで走らせている内容は、ほぼほぼコレでサーバサイドで出来ちゃいます。

- [Google PageSpeed Module | Google Developers](https://developers.google.com/speed/pagespeed/module/)

# PageSpeed Moduleの設定値

.htaccessに以下の内容を記載。利用は自己責任で。

```ssh

# mod_pagespeed

# pagespeedの有効化
#ModPagespeed off
ModPagespeed on

# 有効化
ModPagespeedEnableFilters sprite_images,rewrite_css,combine_css,inline_google_font_css,prioritize_critical_css,outline_css,remove_comments,collapse_whitespace
#ModPagespeedEnableFilters rewrite_javascript,combine_javascript,inline_javascript,defer_javascript
ModPagespeedEnableFilters rewrite_javascript,combine_javascript,inline_javascript
ModPagespeedEnableFilters make_google_analytics_async,trim_urls

# 無効化
ModPagespeedDisableFilters lazyload_images,inline_preview_images
ModPagespeedCriticalImagesBeaconEnabled false
```

ON/OFFは調整で頻繁に利用するので、コメントアウトで切り替えられるようにしておいたほうがラクです。
あとは、有効と無効を明示的に記述するほうが、把握しやすいです。基本的にカンマ区切りで記述していけるのですが、自分がわかりやすい項目ごとに、行を変えたほうがいいと思います。CSS用とかJS用とか画像用とか。

## わりとハマるポイント

JSもCSSも結合してくれる処理( combine_css, combine_js )があるのですが、JSを結合するとページでエラーが出やすいです。CSSはレイアウト崩れが起きやすいです。結合系の処理は、しっかりと検証しましょう。
あと、画像最適化は軽くなるんですが、結構荒くなります。注意が必要です。

## 個人的に良かったポイント

画像のWebP配信はいいですね。ブラウザ判定して、対応ブラウザにはWebP配信してくれます。JPGから比べても1割くらい軽くなります。
GAタグを非同期で読み込んでくれるとか、CSSの主要なレイアウトの記述をページ側に記述してくれるとか、ページ最適化をかゆいところに手が届くレベルで自動で処理してくれます。便利です。
あとは、インストールはコマンド数行で終わりますし、.htaccessで設定できるのも便利です。confに書かないので、リスクを減らせます。

### 参考サイト

- [表示高速化をできるだけかんたんに！GoogleのPageSpeedモジュールをインストールして、お手軽に高速化しちゃおう！](https://blog.ideamans.com/2018/04/pagespeed-module.html)
- [スマホ表示最速王決定戦！CMSプロレスvol.03に参加してきました！](https://blog.ideamans.com/2018/02/cmsvol03-result.html)
- [強引にKUSANAGIにngx_pagespeedを入れて動かしてみる](https://a-lab.biz/1218)
ログインシェルの変更


####背景
.bashrcでPATHを通し、Pythonのデフォルト使用をPython3に設定しているにもかかわらず
ターミナルを開き直すとPython2に戻っていることがあった。


####原因
ログインシェルが、bashではなく、zshに変わっていた


####変更方法

```
$ chsh -s 変更したいログインシェル
```

例
```
$ chsh -s /bin/bash
```
先頭0埋めの値の演算

##概要
bashのfor文で、1ずつ加算し、
演算後、2桁の数値になるように先頭を0埋めした値
(欲しい出力は01,02,03,04,05,....10,11,12 というかんじ)
を出力させるということをしたかった。
そのときの試行錯誤3つをまとめたもの

##まとめ
1.先頭0埋めの数値に加算すると通常の数値になる、
2.$((a+b))の演算では、先頭0埋めの数値は8進数とみなされ、08以上の値への加算ができない
3.exprを使うと、先頭0埋めの数値も10進数として計算可能


##その1
先頭を0埋めした数値に加算をする。

```.bash
#!/bin/bash
id=`printf %02d 6` #2桁になるよう1桁のものは0埋めする、ここでは'06'

echo $id
for i in ` seq 1 6`
do
  id=$((id + 1))
done
```

結果:
最初のechoでは、0埋めの$idが出力されているが、
加算後は1桁の$idになっていることより、
先頭0埋めの数値に加算すると通常の数値になる
例)06+1=7,   06+2=8,  06+3=9.......


```
06
7
8
9
10
11
12
```


##その2
その1より、加算後に0埋めが無効になることがわかったので、ループの最後に0埋め変換する

```.bash

#!/bin/bash
id=6
echo $id

for i in ` seq 1 6`
do
  echo "ループ開始 ${id}"
  echo "$id +1"
  id=$((id+1))
  echo "加算後 ${id}
  id=`printf %02d $id`

done
```


結果:
`06+3`、`07+3`は計算できるが、`08+1`は計算ができず、途中で止まってしまう。
先頭に0がついていると8進数にみなされるため、計算できないよう。
（8進数では８や9は存在せず、1~7が終わったら11~17, 21~27 となる）


```
6
ループ開始　6
6 +1
加算後 7
0埋め変換後 07
ループ開始　07
07 +1
加算後 8
0埋め変換後 08
ループ開始　08
08 +1
ベースの値には大きすぎます
```


##その3
その2の対処方法。0埋めの数値を8進数ではなく10進数として計算する。

```.bash

#!/bin/bash
id=6
echo $i

for i in ` seq 1 6`
do
  　echo "ループ開始 ${id}"
  　echo "$id +1"
    id=`expr $id + 1`
    echo "加算後 $id"
    id=`printf %02d $id`
 　 echo "0埋め変換後 ${id}"
done
```


結果:
exprを使うと、0が先頭についている値も10進数として計算してくれる。
※計算できるが0埋めは消えるので出力の際に0埋めをする必要がある。


```
6
ループ開始　6
6 +1
加算後 7
0埋め変換後 07
ループ開始　07
07 +1
加算後 8
0埋め変換後 08
ループ開始　08
08 +1
加算後 9
0埋め変換後 09
ループ開始　09
....
```
EC2にPHP7.2を導入することに躓いたので独自目線で纏めた

# はじめに
EC2で環境構築をすることになったのですが、やったらとっても躓いたのでまとめました。
後から見返す用ですが、同じことをやる人たちのための参考になれば幸いです。

## 参考
https://qiita.com/Ikumi/items/8f76d074134b7080d102
※他にも参考にしたサイトはあるので思い出したら記載します

# 躓いたリスト
## そもそもPHP7をどうやって入れるか
これは先人たちの知恵がググったら出てきたのでまだ分かりました。

```:/etc/yum.repos.d/remi-php72.repo
[remi-php72]
enabled=1
priority=1
```
これでphp7.2がインストール可能になります。
priorityの意味は後述。

## php-devel入らないんですけど
引っかかったポイント1。

```:/etc/yum.repos.d/remi.repo
[remi]
enabled=1
priority=2
```

```:/etc/yum.repos.d/epel.repo
[epel]
enabled=1
priority=11
```

amzn-main.repoがpriority=10なので、
ここではpriority=11とします。
優先度はamzn-mainが先ですね。

## php-gd入らないんですけど
引っかかったポイント2。

```:/etc/yum.repos.d/epel.repo
[epel]
enabled=1
priority=9
```
amzn-main.repoがpriority=10なので、
ここではpriority=9とします。
優先度はepelが先ですね。

# priorityってなんだよ
「yum-plugin-priorities」をインストールすることによって有効になるオプションです。
priority=優先という意味合いの通り、リポジトリの優先度を決める数値になります。
AWSEC2ではこれがデフォルトで有効になっており、
上記の通り「amzn-main」や「amzn-update」では「priority=10」とデフォルト設定されています。
このため、オプションなしでyum install を実行しようとした場合は、
予めリポジトリ設定ファイルでpriorityを変更しておく必要があります。

## ついでに
AWSEC2のremi.repoやepel.repoはデフォルトで「enabled=0」になっています。
この辺りで躓く人も多いかもしれません。


# おわりに
AWSだとphp-develとphp-gdを同時に入れる術が無い様子です。。
yum install でオプションをつければ確かに入りますが、
「それってupdate来たときどうすんの？」って聞かれると明確な返答が出来ませんでした。。

「こうしました！」って体験談などコメントで頂ければ幸いです。
私も次回の環境構築ではもうちょいスマートにやれればなぁとか色々思います。では。
Solidityの変数の格納領域（storage, memory, stack）

アカウント毎に３つの領域（storage, memory, stack）を持つようだ。

## storage
ブロックチェーンに記録され、永続化される領域。
KVS（256bit => 256bit）
ブロックチェーンに記録されるため、高コスト（高gas）である。
struct, array, mappingの型のローカル変数はデフォルトでstorageに格納される。

## memory
各メッセージ（contractのインスタンス？）に対して、毎回新たに作られる領域。なので、永続化されない。
storageより低コストだが、メモリ領域を拡張する際にコストがかかるようだ。
関数の引数はデフォルトでmemoryに格納される。

## stack
小さな値を内部で保持する際に使う。
コストはほとんど掛からないが、サイズに制約がある。
struct, array, mapping以外のvalue型ローカル変数（参照型で無いものという意味？）はデフォルトでstackに格納される。

## まとめ
変数が格納される領域によって、ライフタイムとコスト（gas）が異なるようなので、考慮した設計にすることが必要。

## 課題
・stackのサイズについてよくわかっていない

参考：
solidity official: 
https://solidity.readthedocs.io/en/latest/frequently-asked-questions.html#what-is-the-memory-keyword-what-does-it-do
http://solidity.readthedocs.io/en/develop/introduction-to-smart-contracts.html?highlight=storage%20memory#storage-memory-and-the-stack
（英語がスラスラ読めるようになりたいなぁ。）
[Linux][Ubuntu] Windows 10インストール用USBメモリをUbuntu上で作成する

# これはなに？

Ubuntuマシンしか持たないひとが、Windows 10のインストーラを作成するお話です。

# 手順

WoeUSBを使います。手順としては、下記URLに書いてあるとおりです。

http://www.webupd8.org/2017/06/tool-to-create-bootable-windows-usb.html


## :one: Windows 10のISOイメージを用意

Windows 10のISOイメージをダウンロードします。

https://www.microsoft.com/ja-jp/software-download/windows10ISO

## :two: WoeUSBをインストール

```bash
sudo add-apt-repository ppa:nilarimogard/webupd8
sudo apt-get update
sudo apt install woeusb
```

[オプショナル] aptレポジトリを削除します。

```bash
sudo add-apt-repository --remove ppa:nilarimogard/webupd8
sudo apt-get update
```

## :three: ISOファイルをUSBメモリへ書き込み

WoeUSBを起動します。

ISOファイルと、書き込み先USBメモリを選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/59475/1a5ddd95-9de1-e24f-1018-c1cba6af6c5c.png)


待ちます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/59475/20ca9911-a033-1cf5-63eb-95653e1e06b7.png)


これでおしまいです。
お疲れ様でした。
型変換に関する機能を試す (Oracle Database 12c Release 2) 

# データ型変換
 SQL文内やPL/SQLプログラム内で、データ型を変換することがあります。データ型の変換にはCAST関数やデータ型に応じたTO_*関数等を利用します。例えば数字を文字列に、文字列を日付に変換する場合には以下のようなSQL文を実行します。

```
SQL> SELECT TO_CHAR(1234, '9999') FROM DUAL;

TO_CH
-----
 1234

SQL> SELECT TO_DATE('2018/04/02', 'YYYY/MM/DD') FROM DUAL;


TO_DATE(
--------
18-04-02

```

しかし、常にデータ型の変換が正常に行われるとは限らず、変換できない値を指定された場合にはエラーが発生します。エラー発生時に適切な動作を行うために、PL/SQLプログラムでは例外が発生した場合のEXCEPTIONブロックが必要になります。

下記の例はTO_DATE関数による日付変換がエラーになった場合にErrorを表示されるPL/SQLブロックです。

```
SQL> SET SERVEROUTPUT ON
SQL> DECLARE
  v DATE;
BEGIN
  SELECT TO_DATE('abcd/ef/gh','YYYY/MM/DD') INTO v FROM DUAL;
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('Error');
END;
/

Error

PL/SQLプロシージャが正常に完了しました。

```

# VALIDATE_CONVERSION関数
Oracle Database 12c Release 2 の新機能であるVALIDATE_CONVERSION関数を使うと、変換エラーが発生するかどうかを例外を発生させることなく事前にチェックすることができるようになります。
VALIDATE_CONVERSION関数に変換前の値と、変換が必要なデータ型を指定すると、変換可能な場合には0を、変換できない場合には1を返します。

構文

```
VALIDATE_CONVERSION( 変換前データ AS データ型 ）
VALIDATE_CONVERSION( 変換前データ AS データ型, フォーマット指定 ）
VALIDATE_CONVERSION( 変換前データ AS データ型, フォーマット指定, NLS指定）

```
実行例
正常に変換できる例（１番目と２番目）とエラーになる例（３番目）です。

```
SQL> SELECT VALIDATE_CONVERSION(100 AS BINARY_DOUBLE) FROM DUAL;

VALIDATE_CONVERSION(100ASBINARY_DOUBLE)
---------------------------------------
                                      1

SQL> SELECT VALIDATE_CONVERSION('2018/03/31' AS DATE, 'YYYY/MM/DD') FROM DUAL;

VALIDATE_CONVERSION('2018/3/31'ASDATE,'YYYY/MM/DD')
---------------------------------------------------
                                                  1

SQL> SELECT VALIDATE_CONVERSION('abcd/ef/gh' AS DATE, 'YYYY/MM/DD') FROM DUAL;

VALIDATE_CONVERSION('ABCD/EF/GH'ASDATE,'YYYY/MM/DD')
----------------------------------------------------
                                                   0
```

# CAST関数
TO_DATE関数やTO_CHAR型関数と異なり、CAST関数は変換先のデータ型をパラメーターで指定できます。Oracle Database 12c Release 2では、型変換がエラーになった場合に返す値をしていできるようになりました。

構文

```
CAST( 変換前データ AS データ型 DEFAULT 値 ON CONVERSION ERROR)
CAST( 変換前データ AS データ型 DEFAULT 値 ON CONVERSION ERROR, フォーマット)
CAST( 変換前データ AS データ型 DEFAULT 値 ON CONVERSION ERROR, フォーマット, NLS指定)

```

実行例1
文字列をBINARY_DOUBLE型に変換し、変換エラーが発生した場合は0.0を返す（変換は正常に行われる）。

```
SQL> SELECT CAST('123.4567' AS BINARY_DOUBLE DEFAULT 0.0 ON CONVERSION ERROR) FROM DUAL;

CAST('123.4567'ASBINARY_DOUBLEDEFAULT0.0ONCONVERSIONERROR)
----------------------------------------------------------
                                                1.235E+002

```

実行例2
文字列をDATE型に変換し、変換エラーが発生した場合は当日日付を返す（変換エラーが発生する）。

```
SQL> SELECT CAST('2018/02/29' AS DATE DEFAULT SYSDATE ON CONVERSION ERROR, 'YYYY/MM/DD') FROM DUAL;

CAST('20
--------
18-04-02

```
phalconのチュートリアル学習記録 -Performance編-

phalconのチュートリアルを学習してみます。

こちらを元に勉強しました。

[phalconチュートリアル学習記録 -Performance編-](https://docs.phalconphp.com/en/3.2/performance)

MacでXAMPPを使用しています。

このチュートリアルでは、パフォーマンスの向上について述べられています。

#xdebugを入れる



1.インストールする
ターミナルで以下を入力

```
brew install homebrew/php/php70-xdebug
```

そしたら、こんなのが出てきました

```
/usr/local/Cellar/php70-xdebug/2.6.0: 4 files, 225.6KB
```

これ、どこなん笑

```
cd /usr/local/Cellar/
```

これで行ったら、無事にありました。

/usr/local/Cellar/php70-xdebug/2.6.0の中に、xdebung.soがあるのを確認してください。

2. php.iniを編集

php.iniの最後の方に以下のコードを付け足します。

```
[xdebug]
zend_extension=/usr/local/Cellar/php70-xdebug/2.6.0/xdebug.so //xdebug.soまでのパス
xdebug.remote_enable=1
xdebug.profiler_enable = On
xdebug.profiler_output_dir = /tmp
xdebug.trace_output_dir = /tmp
```

3. phpinfoをみる

apacheを再起動して、phpinfo()を覗いてください。
Command+Fで検索かけて、「xdebug」が見つかったらオッケーです。


#webgrindを入れる

インストールしてから3時間くらい経過してこの記事を書いているんですが、
どうやって、インストールしたっけ・・・笑

多分、このサイトからかな？
まあ、このサイトでインストールできるみたいなので、ここからしましょう
[webgrind](https://code.google.com/archive/p/webgrind/)


これをXAMPPのhtdocs上にインストールしました。

そして、localhost/webgrindにアクセスしすると・・・

できたっ！！

終わります。
cakephp3 で debug.log, error.log のIPアドレスをロードバランサーではなく、送信元IPアドレスで出力したい

弊社は、CakePHP3.5のアプリケーションが動くWebサーバの手前にAWSのALB（Application Load Balancer）が存在します。
独自のアプリケーションログに関しては、X-Forwarded-Forヘッダを参照し、ログに出力していたのですが、cakephp3が提供するログに関してはデフォルトのままの運用となっていました。

```
2018-03-02 03:36:53 Error: [Cake\Network\Exception\XxxxxxException] Xxxxxxxxxx in /aaa/bbb/ccc/ddd/YyyyyyyyController.php on line 155
Request URL: /eee/ffff/
Client IP: {ロードバランサーのIPアドレス}
Stack Trace:
#0 ......
```

これが、エラー発生時にデバッグしづらい！！

1. エラーの発生時間帯を確認
    - msec単位で同じくらいの時間帯をある程度幅でおぼえておく
2. アクセスログとつきあわせ
    - URLが同じやつはどこだー

なんてことをたまにやってて、もう我慢できない！ということになりました。

# バージョン

- CakePHP v3.5.13
- PHP　7.2.3

# どうやるか

とりあえず、公式ドキュメントを見てみましょう。

https://book.cakephp.org/3.0/ja/controllers/request-response.html#id12

そう、たった１行でできちゃいます。

```AppController.php

// initialize()メソッドに追記
$this->request->trustProxy = true;
```

X-Forwarded-ForヘッダをCakePHPのアプリケーションで使うためには、上記の設定を入れます。

```
2018-04-01 13:45:55 Error: [Cake\Network\Exception\XxxxxxException] Xxxxxxxxxx in /aaa/bbb/ccc/ddd/YyyyyyyyController.php on line 121
Request URL: /eee/ffff/
Client IP: {リクエスト送信元のIPアドレス}
Stack Trace:
#0 ......
```

これで、エラーが発生したときに、一目で送信元が特定できるようになりました！

GoogleのクローラーのIPアドレスがある程度把握できているので、実際のお客様のエラーなのかクローラーのエラーなのかが瞬時に判断つくので、めっちゃ便利です。
新規登録系のバリデーションで気をつけること

# 概要

登録にバリデーションをかけないとサービスが止まったりすることもあるよというまとめ。

# 前提

以下の点は実装で抑えられていることを前提として話を進める。


1. セキュリティ的な実装(CSRF対策などいろいろある)


# 注意点

よくファイルアップロードや、記事の登録などあるが、その時にファイルサイズや登録しようとするサイズが大きすぎて、メモリのオーバフローなどが起こることがある。それを防ぐためにやるべき施策をまとめる。ただし、最初からそれを気にしてもしょうがないので、温度感としては一度出たら実装するくらいで良いと考える。
WordPress テーマを Git 管理して自動デプロイする

WordPress のテーマディレクトリを Git 管理するのは良いが、少し修正するたびにサーバで `git pull` コマンドを実行するのが面倒くさい。

GitHub などのリモートリポジトリに push したら、自動で `git pull` が実行されて反映されるようにしたい。

## 流れ
0. リモートリポジトリに `git push` したら WordPress に Webhook が飛ぶ
0. Webhook を受け取った WordPress はテーマディレクトリで `git pull` を実行する

簡単！(？)

もしかしたら何らかの WordPress プラグインで実現できるかもしれないけど、そのあたりは詳しくないのでわからない。

## テーマディレクトリを Git で管理するようにしておく
前提として、テーマディレクトリ (`/wp-contents/themes/<テーマ名>/`) 以下を Git リポジトリとして管理し、何らかのホスティングサービス (GitHub など) をリモートリポジトリとして設定してあるものとする。

詳しい設定方法は割愛。

## `nginx` ユーザで `git pull` できるようにする
今回 WordPress は Nginx + php-fpm で動いていたので、`nginx` ユーザで `git pull` できるようにしたい。もし Apache + mod_php で動いている場合は `apache` ユーザに置き換えて考えてもらえればいいと思う。

まず、リポジトリにアクセスするための秘密鍵ファイルを配置する。
場所はどこでも構わないが今回は `/home/nginx/.ssh/` 以下に置いた。
パーミッションが適切でないと SSH コマンド実行時に怒られるので注意。

``` console
# ls -l /home/nginx/.ssh/
total 8
-rw------- 1 nginx www 1679 Apr  2 11:32 id_rsa
-rw-r--r-- 1 nginx www  407 Apr  2 11:32 id_rsa.pub
```

次に、環境変数 `GIT_SSH` を指定することで Git コマンドから SSH 接続する際の秘密鍵を指定する。
※ もしサーバにインストールされている Git のバージョンが 2.3 以上なのであれば、`GIT_SSH_COMMAND` が使えるのでそちらを使ったほうが便利ではある。

以下のスクリプトを (今回は) テーマディレクトリのルートに配置する。

``` sh:git-ssh.sh
#!/bin/sh

ssh -i /home/${USER}/.ssh/id_rsa "$@"
```

環境変数 `GIT_SSH` にこのスクリプトのパスが指定されていた状態で `git` コマンドを利用した場合、このスクリプト経由で `ssh` コマンドが実行される。

### 試しに `git pull` してみる
``` console
$ sudo -u nginx GIT_SSH=git-ssh.sh git pull
```

## WordPress のエンドポイントを追加する
`functions.php` などで `wp_ajax_nopriv_XXX` という名前のアクションを追加すると、 `GET /wp-admin/admin-ajax.php?action=XXX` というエンドポイントから指定した関数を実行することができる。

``` php:functions.php
/**
 * Add deploy hook endpoint
 */
add_action('wp_ajax_nopriv_update_theme', 'update_theme');
function update_theme() {
  $git_root = dirname(__FILE__);
  exec("cd ${git_root} && GIT_SSH=git-ssh.sh git pull 2>&1", $out);
  echo join("\n", $out);
}
```

今回は `update_theme` というアクションで `git pull` が実行されるようにした。

## リモートリポジトリへの push 時に Webhook URL を叩く
GitHub / Bitbucket / GitLab などの Git ホスティングサービスでは、リポジトリへ push した際に指定した Webhook URL にリクエストを投げることができる。(設定方法はサービスごとに異なるので割愛)

これに先ほど作成したエンドポイントの URL を指定しておくと、リポジトリに push された際に  WordPress サーバのテーマディレクトリで `git pull` が実行されるようになる。
Rofiの設定

#はじめに
私はArch Linuxでi3wmを使っています。これまでランチャーはi3wmの標準のdmenuを使っていました。しかし、dmenuはカスタマイズ性とおしゃれさに欠けるのでRofiに移行しました。

#Rofiの設定ファイル
``` #.config/rofi/config.rasi
configuration {
  modi: "window,drun,system:~/.config/rofi/rofi_system.sh";
  sidebar-mode:  true;
  hide-scrollbar: true;
  kb-cancel: "Escape,Control+bracketleft";
  kb-mode-previous: "Alt+u";
  kb-mode-next: "Alt+i";
}
@theme "/usr/share/rofi/themes/Arc-Dark.rasi"
```
modiに有効にするモードを設定します。独自のモードも作れます。
kb-(コマンド)にはキーバインドを設定します。rofi -show keysでキーバインドのの設定が見れるので、気に入らないキーバインドを変更します。
themeでテーマを設定する。`rofi-theme-selector`でテーマのpreviewを見ながら設定を変更できます。

#独自のモード
シェルスクリプトで記述します。表示したい項目を改行区切りで標準出力に出力します。選択すると選択した文字列を引数として再度シェルスクリプトを実行します。

```bash
#!/usr/bin/env bash

set -euCo pipefail

function main() {
  # 表示したい項目と実際に実行するコマンドを連想配列として定義する。
  local -Ar menu=(
    ['Lock']='dm-tool lock'
    ['Logout']='i3-msg exit'
    ['Poweroff']='systemctl poweroff'
    ['Reboot']='systemctl reboot'
  )

  local -r IFS=$'\n'
  # 引数があるなら$1に対応するコマンドを実行する。
  # 引数がないなら連想配列のkeyを表示する。
  [[ $# -ne 0 ]] && eval "${menu[$1]}" || echo "${!menu[*]}"
}

main $@
```
![2018-04-02-132029_1366x768_scrot.png](https://qiita-image-store.s3.amazonaws.com/0/163210/923a0595-c451-5a31-45e6-92adf51ed1eb.png)

###コマンドを実行時に確認を取る
独自のモードでpoweroffを実行するのですが、誤って実行する可能性があります。なので、実行を行う時に確認をとるようにシェルスクリプトを変更します。選択すると(項目名 / yes, 項目名 / no)が表示され、yesを選択するとコマンドを実行する。noを選択すると元に戻る。

```bash
#!/usr/bin/env bash

set -euCo pipefail

declare -Ar menu=(
  ['Logout']='i3-msg exit'
  ['Poweroff']='systemctl poweroff'
  ['Reboot']='systemctl reboot'
)

function print_keys() {
  local -r IFS=$'\n'
  echo "${!menu[*]}"
}

function main() {
  local -r yes='yes' no='no'

  if [[ $# -eq 0 ]]; then
    print_keys
  elif [[ $# -eq 1 ]]; then
    echo $1 ${no}
    echo $1 ${yes}
  elif [[ $2 == ${yes} ]]; then
    eval "${menu[$1]}"
  elif [[ $2 == ${no} ]]; then
    print_keys
  fi
}

main $@
```
![2018-04-02-132428_1366x768_scrot.png](https://qiita-image-store.s3.amazonaws.com/0/163210/03d74db5-38ce-2e2d-61ad-43ae788be2c3.png)
AWS Direct connectの略称がなぜDXなのか

## 結論
たぶんですよ、たぶん。

**D**irect connect over **Cross**-network connectionの略なんじゃないかと思います。 
**Cross → X**
で、**DX**。

英語版ドキュメントなんかで明確な出展が分かる人いたらコメントください。
以下に経緯と考察載せておきますので、暇な人はどうぞ。

## 経緯
私は略称を聞いた時に正式名称が気になるタチです。
そして記憶を定着させる為に略称と正式名称がセットになっている必要がある人なんです。
必須プロパティです。なんかのフォームだったら *[アスタリスク] ついてます。

で、本題ですがAWS界隈では Direct connectの事をDXって呼ぶ人が多いです。でぃーえっくす。
私も顧客に対して、そりゃーもう、でぃーえっくすでぃーえっくす言うております。

ある時ふと、でぃーえっくすのえっくすとはなんぞやと思いまして調べてみました。
なるほど、AWSの日本語ドキュメントは一通り読みましたが書いてありません。
頼みの綱 SA 吉田英世さん著の Black Belt も読みましたが書いてありません。

## 考察
DCなんて略称じゃ、データセンターだの、直流だの、確定拠出年金だの、かぶりが多くて使いにくいのは想像出来ました。
で、Xってのは多分 Exchange かCrossのどっちかだろうと拙い英語力で想像しました。

Directconnectの構成作業は、VGW作ったり、AWSに申請上げたりといろいろあります。
AWSへの申請が処理されると、Letter of Authorization and Connecting Facility Assignment (LOA-CFA) というものがマネジメントコンソールからダウンロード出来ます。
その後に東京リージョンだと、Equinix社に クロスネットワーク接続 (別名クロスコネクト) をリクエストします。
https://docs.aws.amazon.com/ja_jp/directconnect/latest/UserGuide/Colocation.html

フムフム、ん？ クロスネットワーク接続？
これじゃね？

ここで構成図を考えます。
![2018-04-02_13h47_49.png](https://qiita-image-store.s3.amazonaws.com/0/99499/b51ae16d-9174-ec8a-510f-5a1e4ed60cc9.png)

なるほど、Directconnectは占有タイプや共有タイプがありますが、ラック間のパッチtoパッチであるcross-network connectionという物理配線の上で展開されるものであることには違いがありません。

という事で、「Direct connect over Cross-network connection」の略なのではと思い至りました。
504 Gateway Time-out が出たので ALB の アイドルタイムアウト 設定変更する


# ALBを導入したらブラウザ上で504 Gateway Time-outエラーが出るようになった

解決のためにまず確認したのは、

1. ALBのCloudWatchモニタリング
2. Apacheのアクセスログ
3. PHPサイトのアプリケーションログ

どのログを見ても、エラーが増えたりはしていない。

Webサーバーまで到達できていないことを考えると、これはApacheやアプリケーションが原因ではない。
おそらくロードバランサーで何かおきてるんだろうとあたりをつけて、ALBの仕様を確認する。

[ALBのドキュメント](http://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-troubleshooting.html#http-504-issues)を確認すると、

> HTTP 504: Gateway Timeout
> 
> 考えられる原因:
> 
> - ロードバランサーは、接続タイムアウトが期限切れになる (10 秒) 前にターゲットへの接続の確立に失敗した。
> - ロードバランサーはターゲットへの接続を確立したが、アイドルタイムアウト期間が経過する前にターゲットが応答しなかった。
> - サブネットのネットワーク ACL で、ターゲットから一時ポート (1024-65535) のロードバランサーノードへのトラフィックが許可されなかった。
> - ターゲットがエンティティ本文より大きな Content-Length ヘッダーを返した。ロードバランサーが欠落しているバイトを待機してタイムアウトした。

なるほど、ALBのタイムアウト設定が短すぎると、Webサーバーからのレスポンスを待ちきれずにエラーが発生したのか。

# ALBの設定画面でアイドルタイムアウトの秒数を確認した

- AWS管理コンソール > EC2 > ロードバランサー 
- 対象のロードバランサーを選択

![2018-04-02_13h25_37.png](https://qiita-image-store.s3.amazonaws.com/0/154018/ab97e90c-61f1-0fcd-5de2-e3d3b56f19ab.png)

- 「説明」タブを選択
- 属性 > アイドルタイムアウト の項目を確認
    - 60秒 と設定があった

- 設定値を伸ばして更新する
    - アイドルタイムアウトの範囲は 1 ～ 3,600 秒です。

無事、504 Gateway Time-outエラーが出なくなりました！

# 参考

[504 Gateway Time-out が出た際は Elastic Load Balancing の設定にも注意しよう](https://qiita.com/kotarella1110/items/169ddcef03983f5d64b2)
data-target 使い方備忘録。


いっぱいある要素のなかで個別に処理をおこないたいとき、クラスだと着け方迷うし
js〇〇〇とかあまりつけたくないのでdata-targetを使って対応。
jquery使ってます。


取得したい要素に以下を追加

` data-target="type1"`


```html:data-target.html
<input id="id" type="radio" name="name" value="1" checked="" data-target="type1">
```


```js:data-target.js
let target = $(this).attr('data-target');
if (target === 'type1') { $('.block1').show(); $('.block2').hide(); }
else { return false; }
```


else if でtargetごとに処理分けれるので、とにかく要素いっぱいあって何やってるかわかりづらい！
ってときに使うと便利。かも。


##一つずつ処理を回したい

処理を回したい要素にclassとdata-targetをつける

```html:data-target.html
<a href="" class="js-each" data-target="キャンペーン詳細">キャンペーン詳細はこちら</a>
<a href="" class="js-each" data-target="キャンペーン場所">キャンペーン場所はこちら</a>
<a href="" class="js-each" data-target="キャンペーンお申込み">キャンペーンお申込みはこちら</a>
```


```js:data-target.js
  $('.js-each').each(function() {
    let $this = $(this);
    let target = $this.attr('data-target');

    if(target === 'キャンペーン詳細') {
      $this.attr('href', 'https://campaign.com/キャンペーン詳細');
    }
    else if (target === 'キャンペーン場所') {
      $this.attr('href', 'https://campaign.com/キャンペーン場所');
    }
    else if (target === 'キャンペーンお申込み') {
      $this.attr('href', 'https://campaign.com/キャンペーンお申込み');
    }
    else {
      return false;
    }
  });
```


なが～いリンクをあちこちにはったりする場合は管理が楽。
GrafanaのDashboard等をファイルで管理する

Grafanaのdatasourceとdashboardは従来REST APIか、GUIを通じてしかexport/importできなくて、Git等で管理するのに少し工夫が必要だったのだけど、v5.0からファイルでの管理に対応した。それについてドキュメント読んでメモしただけの記事。

[Provisioning | Grafana Documentation](http://docs.grafana.org/administration/provisioning/)

ファイルで管理できると、AnsibleやDockerとの相性も良くなってとても楽。

Datasources
-----------

`/etc/grafana/provisioning/datasources/hoge.yml` に設定を以下のように書く。datasourceが複数ある場合、ファイルは分割しても良いし、 `datasources` にmapで複数指定してもよい。

```yaml
apiVersion: 1

datasources:
- name: timeseriesData
  type: influxdb
  access: proxy
  orgId: 1
  url: http://192.0.1.1:8086
  user: user
  password: password
  database: timeseries
  isDefault: true
  editable: false
  version: 1
```

設定を更新したときに `version` をincrementしておけば、古いversionで新しいversionは上書きできなくなっているので安心、みたいなこともドキュメントには書かれているのだが、どうも上手く動かなくて使い方がわからない。

`editable` がデフォルトで `false` になっており、yamlでprovisioningした設定は、GUIからは書き換えできなくなっている。これはyamlからその設定を削除した後も有効。yamlで追加したdatasourceを消すには、 `editable: true` にしてGUIから消すか、 `delete_datasources` に設定するかの2択。

### 一意性

`name` で判断されている。既存のdatasourceと同じ `name` を持つ設定をyamlで準備した場合、yamlの値が優先されて、上書きされてしまうため注意が必要。


Dashboards
----------

こちらは2箇所に設定が必要。まず `/etc/grafana/provisioning/dashboards/hoge.yml` を置く。

```yaml
apiVersion: 1

providers:
- name: 'hoge'
  orgId: 1
  folder: ''
  type: file
  disableDeletion: true
  editable: true
  options:
    path: /var/lib/grafana/dashboards
```

ここで書いた `name` はGUIだと特にどこでも使われていないと思うので、なんでもいい。これは単に、実際のdashboardのjsonを `providers[0].options.path` に置きますよという宣言をしているだけ。あとは `diableDeletion` や `editable` はお好みに応じて。ドキュメントに各設定値の詳細が書かれていないので、今のところ挙動がわかりにくいが、`disableDeletion: true` にしておくと、jsonを削除してもdashboardは削除されなくなる。

実際のjsonは、この場合では `/var/lib/grafana/dashboards` に1つずつ配置する。このjsonは、従前のバージョンからGUIで出力できていた、あの書式で良い。あまりGrafana dashboardをjsonでイチから書く人もいないと思うので、一旦GUIで作ってからexportすればOK。但し、exportした際には付与される `id` という値が、ファイルでのprovisioningの場合は不要となっているので、削っておく必要がある。

### 一意性

`uid` で管理される。uidはGUIから作成したdashboardだとランダムに採番されていて、yamlから作成するときはjsonの中で好きに採番できる（採番しなくてもOKで、その場合はやはりランダムになる）。すでに存在するuidと同じuidでjson設定を書いた場合、そのuidのdashboardが強制的に更新される。uidはdashboardのURLに含まれるため、複数のGrafanaを立てて、同じグラフを双方で表示するとき、一意なURL採番をするのに役立つ。

ただし、注意するべきは `title` も一意である必要があるということ。例えば1つのGrafanaサーバーに、 `title` が同一で、 `uid` は異なるdashboard設定を複数用意しても、後発の設定は反映されない。GUIですでに存在するdashboardの設定をjsonファイルで配置し、別uidを振ったとしても、既存の方のdashboardを一度削除しないことには、jsonの方は反映されない。
Node.jsバージョン管理メモ


最もスターが多い `nvm` を使用
https://github.com/creationix/nvm


インストールできるバージョン一覧を表示

```bash
nvm ls-remote
```

バージョンを指定してインストール

```bash
nvm install v8.11.1
```


インストール済みのバージョン一覧を表示

```bash
nvm ls
```

```bash
         v6.3.1
        v6.11.3
         v7.3.0
->      v8.11.1
        v9.10.1
         system
default -> 7.3.0 (-> v7.3.0)
node -> stable (-> v9.10.1) (default)
stable -> 9.10 (-> v9.10.1) (default)
iojs -> N/A (default)
lts/* -> lts/carbon (-> v8.11.1)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.14.1 (-> N/A)
lts/carbon -> v8.11.1
```

使用するバージョンを変更

```bash
nvm use 8.11.1
```

デフォルトのバージョンを変更

```bash
nvm alias default 8.11.1
```

※Nodejsを複数箇所からインストールしている場合、衝突している可能性があるので`where`コマンドで確認する


> 参考
[いまアツいJavaScript！ゼロから始めるNode.js入門〜5分で環境構築編〜](http://liginc.co.jp/web/programming/node-js/85318)
[Windows における Node.js バージョン管理マネージャの選択（nvm-windows, nodist 等）](http://blog.clock-up.jp/entry/2018/02/10/nodejs-manager-on-windows)
Homebrew/scienceがbrewsci/bioに移動された話

ちょっと前(といっても2017年前半まで)ぐらいの、Bioinformatics関連の本を読んでいると、次のコマンドで環境を構築していると思う。

``` 
$brew install homebrew/science/"FORMULA"
```

以前はこの記述でなんの間違いもなかったのだろうが、2018年4月現在、homebrew-scienceは廃止されてしまったので、上記の記述では動かない。
その代わり、以下のコードで対応できる。

```
$brew tap brewsci/science
brew install "FORMULA"
```

```
$brew tap brewsci/bio #バイオインフォマティックス関連
brew install "FORMULA"
```

参考:
https://github.com/Homebrew/homebrew-science/issues/6617
Python > link > a local variable table called a local namesapce | try_to_modify関数呼び出しメモリレイアウト

@ Scipy Lecture notes, Edition 2017.1
p28
2.4.4 Passing by value
@ Web
https://www.scipy-lectures.org/intro/language/functions.html#passing-by-value

> Function have a local variable table called a local namespace.

コメントいただいた事項で関連するのは下記

- [Python > id() / global を試してみた > id()が返すID / 代入先の辞書 {ローカル辞書 / グローバル辞書} | locals(), globals()](https://qiita.com/7of9/items/c93925f315cfc5e45788)
- [Python > zip(*list4) > 行列の変換 > リストやタプルの引数展開 / 辞書引数展開 / ローカル変数辞書 locals()](https://qiita.com/7of9/items/e23bdd6e8d4d7997104a)


### 謝辞 > try_to_modify関数呼び出しメモリレイアウト

@shiracamus さんにコメントにて分かりやすい図を掲載いただきました。

お手数おかけいたします。
平成28年度情報処理・通信技術者派遣料金

[平成28年度 労働者派遣事業報告書の集計結果](http://www.mhlw.go.jp/file/04-Houdouhappyou-11654000-Shokugyouanteikyokuhakenyukiroudoutaisakubu-Jukyuchouseijigyouka/0000117568_3.pdf)
が公表されたため(平成30年3月30日)賃金部分だけ抜粋。
今年はソフトウェア開発の分類が無いため、情報処理・通信技術者を使用しています。

>昨年のは[平成27年度ソフトウエア開発派遣料金](https://qiita.com/sacred-sanctuary/items/641f945727f06d84aaf5)を参照

#派遣料金
![平成28年度労働者派遣事業報告書派遣料金.jpg](https://qiita-image-store.s3.amazonaws.com/0/170755/6ec37e39-5b6e-361b-8afe-da5ca3e9e7b5.jpeg)
情報処理・通信技術者(一般派遣)の平成28年の派遣料金は_30,389円/日(8H)_
情報処理・通信技術者(特定派遣)の平成28年の派遣料金は_31,664円/日(8H)_
１ヶ月ですと一般派遣では_607,780円/月(20日)_位
１ヶ月ですと特定派遣では_633,280円/月(20日)_位
ですかね。

##参考単価表
###一般派遣参考単価表
| 契約時間 | 平均単価 |
|:-----------|------------:|
| 160H | 607,780円 |
| 140H - 180H | 531,807円 - 683,752円 |
| 140H - 200H | 531,807円 - 759,725円 |
###特定派遣参考単価表
| 契約時間 | 平均単価 |
|:-----------|------------:|
| 160H | 633,280円 |
| 140H - 180H | 554,120円 - 712,440円 |
| 140H - 200H | 554,120円 - 791,600円 |
#賃金
![平成28年度労働者派遣事業報告書派遣労働者の賃金.jpg](https://qiita-image-store.s3.amazonaws.com/0/170755/1df22029-3777-5dc5-8781-10ff60a2e482.jpeg)

情報処理・通信技術者(一般派遣)の平成28年の賃金は_18,527円/日(8H)_
情報処理・通信技術者(特定派遣)の平成28年の賃金は_18,829円/日(8H)_
一ヶ月では
情報処理・通信技術者(一般派遣)の平成28年の賃金は_370,540円/月(20日)_位
情報処理・通信技術者(特定派遣)の平成28年の賃金は_376,580円/月(20日)_位
一年では
情報処理・通信技術者(一般派遣)の平成28年の賃金は_4,446,480円/年(12ヶ月)_位
情報処理・通信技術者(特定派遣)の平成28年の賃金は_4,518,960円/年(12ヶ月)_位

#マージン率
上記から計算すると
情報処理・通信技術者(一般派遣)の平成28年のマージン率は_約39%_となります。
情報処理・通信技術者(特定派遣)の平成28年のマージン率は_約40%_となります。

#マージン率からの参考給料
| 単価 | 月収 | 年収 |
|:-----------|------------|------------:|
| 60万円 | 36万円 | 432万円 |
| 65万円 | 39万円 | 468万円 |
| 70万円 | 42万円 | 504万円 |
| 75万円 | 45万円 | 540万円 |
| 80万円 | 48万円 | 576万円 |
| 85万円 | 51万円 | 612万円 |
| 90万円 | 54万円 | 648万円 |

#その他
（旧）特定労働者派遣事業に係る経過措置の
経過措置期間は平成30年９月29日までです。
平成30年９月30日以降は、
（旧）特定労働者派遣事業が行えなくなります！
>[（旧）特定労働者派遣事業を行っている事業主の皆さまへ
](http://www.mhlw.go.jp/file/06-Seisakujouhou-11600000-Shokugyouanteikyoku/0000178229.pdf)を参照

現在特定派遣で働いている方は注意が必要です。
Python > list > a[:] = [1, 2, 3] > identityを変更しない代入

```txt:動作環境
ideone (Python 3.5)
```

@ Scipy Lecture notes, Edition 2017.1
p21 2.2.3 Assignment operator
@ Web版 1.2.2.3. Assignment operator
https://www.scipy-lectures.org/intro/language/basic_types.html#assignment-operator

```py
In [6]: id(a)
Out[6]: 138641676
In [7]: a[:] = [1, 2, 3]  # Modifies object in place
In [9]: id(a)
Out[9]: 138641676  # Same as in Out[6], yours will differ...
```

上記のようなaへの代入だとidentityは変更されないとのこと。

ideoneでもidentityは変更されなかった。

https://ideone.com/NrhutQ

```py
a = [1, 2, 3]
print(id(a))

a = [4, 5, 6]
print(id(a))

a[:] = [7, 8, 9]
print(id(a))
```

```txt:run
47713454781832
47713454783560
47713454783560
```

identityを変更しないことによる利点については未消化。
Flash の サポートは「2020年末」まで

### Adobe の コメント

[Flash とインタラクティブコンテンツの未来](http://blogs.adobe.com/japan-conversations/201707adobe-flash-update/)

>私たちはカスタマーやパートナーが移行計画を実行する期間、2020年末まで引き続きFlashのサポートに努めます。予定されているサポートの終了までは、現在Flashコンテンツを表示する主要なOSおよびブラウザに対してFlashのサポートは継続します。

### Microsoft の コメント

[Internet Explorer および Microsoft Edge での Flash の今後の対応予定について](https://blogs.technet.microsoft.com/jpieblog/2018/03/23/flash-roadmap/)

>2020年末、サポートされるすべての Windows 上の Microsoft Edge および Internet Explorer で Flash を実行することができなくなります。Flash を再び実行できるように構成することもできなくなる予定です。

### まとめ

2020年末のWindows Updateで強制的にFlashを消す可能性があります。それまでにFlashで作られているシステムはフロントエンド部分だけでも、移行を完了させておくことが必要ですね。
【PHP】期間外のリクエスト（POST）を受け付けないようにする


# 締め切り後のリクエストは受け付けません

期間内か否かの判定式ってあんまり見たことないので書いてみました。
こんな感じでどうでしょうか

```post_uketoru.php
<?php
// date_default_timezone_set('Asia/Tokyo'); // php.iniの設定
$postTime = new DateTime();

// 受け付け期間（開始日～終了日）
$From = new DateTime('2018-03-01 12:00:00');
$To   = new DateTime('2018-03-31 13:00:00');

// 期間外のPOSTを受け付けない
if ($postTime->diff($From)->invert === 1 && $postTime->diff($To)->invert === 0) {
    // POSTに対する処理
    return true;
}

return false;
```

# おわり
- 厳密にする必要がなかったらFromはいらないかもしれないですね。
- 期間の設定はあくまで現地時間（この場合は日本時間）に設定しておく。
- まあ[Carbon](http://carbon.nesbot.com/)使えるなら使えばいいんじゃないでしょうかね

# 参考
- [PHP: DateInterval - Manual](http://php.net/manual/ja/class.dateinterval.php)
Android Studioを 3.0 から 3.1 へ移行する

## はじめに
[Android Studio 3.1](https://android-developers.googleblog.com/2018/03/android-studio-3-1.html) がリリースされました。
ということで、Android Studioを3.0から3.1に移行しました。

## 手順

### 1. Android Studioのアップデート
`Android Studio -> Check for Updates...`からアップデート

### 2. Gradleのアップデート
Gradle version `4.4` 以上でないといけないので、最新の `4.6` にアップデート

```properties:gradle/wrapper/gradle-wrapper.properties
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
```

### 3. Android Plugin for Gradleのアップデート

```groovy:build.gradle
buildscript {
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.1'
    }
}
```

### 4. SDK Build Toolsのアップデートのアップデート
buildToolsVersionが `27.0.3` 以上でないといけない

```groovy:app/build.gradle
android {
    buildToolsVersion '27.0.3'
}
```

### 5. ビルド環境の設定

#### D8コンパイラ
新しいDEXコンパイラ D8 はデフォルトで使われるので、何もしない
D8コンパイラを使いたくない場合は、以下のように書く

```properties:gradle.properties
android.enableD8=false
```

#### Incremental desugaring
これもデフォルトで使われている
使いたくない場合は以下の通り

```properties:gradle.properties
android.enableIncrementalDesugaring=false
```

#### In-process desugaring in D8
以下のように書く
プレビュー版のため、今回はやらなかった

```properties:gradle.properties
android.enableD8.desugaring=true
```

#### Data Binding Compiler V2
以下の記述を追加

```properties:gradle.properties
android.databinding.enableV2=true
```

それぞれの詳しい内容はこちら
[New DEX compiler, D8](https://developer.android.com/studio/releases/gradle-plugin.html#D8)
[Data Binding Compiler V2](https://developer.android.com/topic/libraries/data-binding/index.html#enable_v2)

### 6. その他行ったこと

#### Data Binding
[DataBindingのkaptを書かなくても良くなった](https://medium.com/@star_zero/databinding%E3%81%AEkapt%E3%82%92%E6%9B%B8%E3%81%8B%E3%81%AA%E3%81%8F%E3%81%A6%E3%82%82%E8%89%AF%E3%81%8F%E3%81%AA%E3%81%A3%E3%81%9F-3634a3ede080) の記事を見て、以下の記述を消しました。

```groovy:app/build.gradle
dependencies {
    kapt 'com.android.databinding:compiler:3.0.1'
}
```

#### Data Bindingエラー ケース1
ビルドしたときに以下のようなエラー
> Type inference failed. Expected type mismatch: inferred type is ***Binding? but ***Binding was expected

RecyclerViewAdapter で以下のように書いていたのが原因。

```kotlin
val binding: **Binding = DataBindingUtil.bind(view)
```

Nullableの形に変えました。

```kotlin
val binding: **Binding? = DataBindingUtil.bind(view)
```

#### Data Bindingエラー ケース2
ビルドしたときに以下のようなエラー
> Type mismatch: inferred type is String? but String was expected

ObservableField で以下のように書いていたのが原因。

```kotlin
val value: ObservableField<String> = ObservableField("")
val binding: String = value.get()
```

Nullableの形に変えました。

```kotlin
val value: ObservableField<String> = ObservableField("")
val binding: String? = value.get()
```

#### .gitignoreの設定
Android Studio 3.1 から `.idea/codeStyles/codeStyleConfig.xml` と` .idea/codeStyles/Project.xml` が新たにファイルが増えた。
これらをGit管理対象外にするために、以下の記述を足した。

```:.gitignore
.idea/codeStyles
```

## 参考
* [Android Studio Release Notes](https://developer.android.com/studio/releases/index.html#3-1-0)
Xcodeでplistのソースコード表示と戻し方

plistのソースコード表示を元に戻したい思った時、info.plistを右クリックしても
<img width="372" alt="Screen Shot 2018-04-02 at 11.56.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/216701/ceb45ebf-d0c9-4807-33ab-3f676ffff8ba.png">
と表示されている場合があります。

画面右上をご確認ください。
<img width="104" alt="Screen Shot 2018-04-02 at 11.57.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/216701/95abbdc7-6ea1-ab1b-ebef-688a56be6de8.png">
この3つのボタンの一番右を選択している状態だと、元に戻すことができません。
<img width="101" alt="Screen Shot 2018-04-02 at 11.59.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/216701/bc0e208d-769d-3421-b540-91130a023a9a.png">
こうすると、元に戻っているはず。

単純ですが、数分悩んだので同じことで悩んでいる人はきっといると思いシェアしました。