OmniAICreator/Qiita-1.07M huggingface dataset:
Sierra/HighSierra で Homebrew/phpbrew でハマった件

macOS Sierra とか High Sierra にして、Xcode9 にした時に、 Homebrew やら phpbrew がいろいろおかしくなった時のメモです。

この問題は、それぞれの環境によるところが大きいと思います。どなたもがこういったことが起こるわけでもなさそうですし、ただ、設定ができない状態では本当に困ってしまうので、対処療法をせざるを得ません。

今回、僕が遭遇した様々なトラブルと同じ目にあう人の助けになればと、Qiita にメモを残すことにしました。（後々の自分のためともいう）

## Sierra と Xcode9 の組み合わせ編

うまくいかない現象と、その解決方法をつらつらと書いていきます。

### brew update に失敗

brew update をした時に

```
/usr/local/Library/brew.sh: line 32: /usr/local/Library/ENV/scm/git: No such file or directory
```

こんなのがでたら

```
brew prune
```

とする

### Homebrew で PHP をインストール

PHP をインストールしようと

```
brew install php70
```

などとするとエラーが出る。

```
brew install php70 --build-from-source
```

と、 `--build-from-source` をつけたらビルドが通るようになった。
これは、PHP 本体だけじゃなくて、拡張のインストールのときも有効です。

### phpbrew でビルドがコケる

```
phpbrew install 5.6.31
```

とかすると

```
configure: error: off_t undefined;
```

というエラーが出る。これの解決法がどうもわからなかった。

```
phpbrew install 7.0.8
```

と別のバージョンを入れようとすると、エラーが変わって、

```
ld: file not found: /usr/lib/system/libsystem_darwin.dylib for architecture x86_64
```

というエラーが出る。こちらは、

```
LDFLAGS="-L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib/system" phpbrew install 7.0.8
```

と `LDFLAGS` でパスを指定すると通った。次の Qiita 記事のおかげです。ありがとうございます。

参考: [PHP7をmacOSでビルドしたらエラーになった](https://qiita.com/grohiro/items/a5f2ccd8a4c8ca8ac7d8)

ということで、この方法で入るならと brew では 5.6 をインストールして、phpbrew で 7系を入れることにした。

```
phpbrew install 7.1.10
```

と、最新版 7.1 を入れようと思ったら、またまた

```
configure: error: off_t undefined;
```

というエラーが出るので、こちらもさっきうまく行った方法でやってみようと、

```
LDFLAGS="-L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib/system" phpbrew install 7.1.10
```

でやってみる。見事にビルドが通った。
さっきのエラーは 5.6 を入れたようとしていた時と同じエラーじゃないですか。それじゃ、ということで 5.6 系でもこの方法でやってみる

```
LDFLAGS="-L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib/system" phpbrew install 5.6.31
```

おお！無事に通った。ということで、Sierra + Xcode9 環境で、phpbrew うまくいかない時は、`.profile` などに

```
export LDFLAGS="-L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib/system"
```

をセットしてやるとうまくいきそうです。

## Hight Sierra と Xcode9 編

さて次は High Sierra です。実は、Sierra 編とは別の Mac です。
Sierra と Xcode9 の組み合わせが良くないのであって、 High Sierra と Xcode9 なら、なんの問題もないだろうと思ってたんですが、いろいろありました。

だけど、これも僕の環境の別な何かが原因なのかもしれません。
発生したのは OpenSSL の `evp.h` ヘッダファイルが見つからないというエラーです。

```
phpbrew install 5.6.31
```

次のエラーが出ました。

```
configure: error: Cannot find OpenSSL's <evp.h>
```

libressl がどうのという話があったので入れてみます。

```
brew install libressl
```

状況変わらず

include ディレクトリにシンボリックリンクを置いてみた

```
cd  /usr/local/include
ln -s /usr/local/opt/openssl/include/openssl .
```

だめ。全く同じエラーが出ます。

次の、コメントに書いてあるようにやってみます。

https://github.com/phpbrew/phpbrew/issues/612#issuecomment-314604913

```
phpbrew install 5.6.31 +default +openssl=/usr/local/Cellar/openssl/1.0.2l
```

通った！
ここまで来るのに、めっちゃ時間かかりました。(´Д｀)ﾊｧ…
IBM DataPower GatewayでLDAPの設定をする

#1. はじめに
とあるお客様のプロジェクトで、IBM DataPower Gateway(以降、IDG)でLDAPの設定をしました。導入実績が少ないこともあり、完了までかなり苦労したので、設定のポイントをまとめます。

#2. この記事の前提
以降の内容は以下を前提としています。

- バージョンはV7.5
- LDAPユーザーでIDGにログインし、LDAPグループ毎に異なる権限を付与する

#3. 設定のポイント
重要なポイントは以下の2点を設定です。

- 認証情報の設定: IDGからLDAPサーバーにバインドするための情報を入力する
- 資格情報マッピングの設定: あるグループを特定するための情報を入力する

具体的には、デフォルトのRBMInfo.xmlファイルには既にサンプル構成が記述されていますが、このファイルをカスタマイズしていきます。

- "InputCredential"タグに、LDAP上に定義されているグループ名を指定する(大文字・小文字が区別されるので注意が必要)。

- "OutputCredential"タグに、上で定義したグループに与えるアクセス権を指定する(例えば、フル権限を与える場合は、"*/*/*?Access=r+w+a+d+x"と指定する)。

以下の例では、TestGruopグループからwrite権限を外しています。例えば、このグループに所属しているユーザーがWebGUI(またはBluePrint Console)にログインし、構成ファイルを変更しようとしても、"edit"のリンクが表示されないため、所望の振る舞いになっていることが確認できます。

```shell-session
  <MapCredentials>
      <InputCredential>TestGruop</InputCredential>
      <OutputCredential>
         */*/*?Access=r+a+d+x
      </OutputCredential>
  </MapCredentials>
```
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/198881/92c56557-8845-732b-2d77-8f1252090408.png)


#4. 設定が上手くいかない場合の考慮点
設定が上手くいかない場合、Error Reportとネットワーク・トレースを取得して問題を切り分けていきますが、IDG独特の考慮点として、Referralメッセージの扱い方を知っておくと有用です。

>参考: IBM WebSphere DataPower SOA Appliance: Searching LDAP server results in message "Unknown reply tag 115" or "failed: Referral"
>http://www-01.ibm.com/support/docview.wss?uid=swg21404222

IDGはLDAPサーバーからのReferralメッセージを受け取ることができません。LDAPの検索フィルターの対象が広過ぎる場合(最初にリクエストを受け取ったLDAPサーバーに情報がない場合)、クライアントに"他のLDAPサーバーを参照して欲しい"というReferralメッセージをLDAPサーバーがクライアントに返します。ところが、IDGはこのメッセージを処理することができないのでエラーとなります。この場合、LDAP側で対応を取る必要がありますが、例えば、検索フィルターを絞り込むなどしてReferralメッセージを送信させないようにする必要があります。

#5. まとめ
IDGでLDAPを設定する際の考慮点をまとめました。ご紹介した内容を意識して作業に取り組むと、プロジェクトを円滑に進めることができると思います。
API ManagerでLDAPを設定する際に知っておきたいこと

#1. はじめに
とあるお客様のプロジェクトで、API ManagerでLDAPを設定する必要がありました。この記事ではAPI Manager(以降、APIM)でLDAPを設定する際に知っておきたいことをまとめます。API Managerと併用することの多いIBM DataPower Gateway(以降、IDG)でLDAPを設定する手順との違いを理解しておくこともポイントです。

#2. この記事の前提
以降の内容は以下を前提としています。

- バージョンはV5.0.7.2

#3. 知っておきたいこと - その1
Cloud Managerコンソール上では、メンバー(ローカル・ユーザー)と組織(グループ)を作成することができます。つまり、ユーザー管理として、ローカル・ユーザー・レジストリーも1つの選択肢としてありますが、ローカル・ユーザー・レジストリーとLDAPレジストリーの併用はできません。

ローカル・ユーザー・レジストリーとLDAPレジストリーを併用しようとすると、以下のような問題点に遭遇します。

- ローカル・ユーザー・レジストリーが設定されている状況では、LDAP構成の保存ができない
- LDAPレジストリーが設定されている状況でメンバーと組織は追加できるが、LDAPの変更ができなくなる(例えば、バインド・パスワードの変更、検索フィルターの変更など)、またLDAP構成の削除もできなくなる

後者のケースで、LDAPの変更が必要となった場合は、"system clean apiconfig"コマンドを実行してAPIMを初期化しなければなりません(ネットワーク以外の設定はすべて失われるので注意)。

#4. 知っておきたいこと - その2
ローカル・ユーザー・レジストリーとLDAPレジストリーの併用ができないことで、以下のような弊害が生じます。

LDAPレジストリーでユーザーを管理した場合、LDAPサーバーがダウンしている間はCloud Managerコンソールに誰もログインできなくなります。IDGでは、Local accounts for fallbackの設定をすることで、LDAPユーザーが誰もログインできない状況でも、fallbackユーザーでのログインを可能にする設定が可能ですが、APIMでは不可能なため注意が必要です。

#5.まとめ
IDGでLDAPを設定する際に知っておきたいポイントをまとめました。要件定義の段階で、ユーザー管理をどちらにするか決定しておくことが重要です。
API Managerをクラスター構成で構築する際の考慮点をまとめてみた

#1. はじめに
とあるお客様のプロジェクトで、IBM APIConnectの1つのコンポーネントであるAPI Manager(以降、APIM)をクラスター構成で構築しました。この記事では、初心者が陥りやすい(クラスター特有の)構築時のポイントをまとめます。

#2. この記事の前提
以降の内容は以下を前提としています。

- API ConnectのバージョンはV5.0.7.2
- クラスターに所属しているAPIMは2つ
- 1台目のAPIMは構築済み
- 2台目のAPIMのネットワーク構成までは設定済み

#3. APIMをクラスターに追加する際の考慮点

APIMのクラスター環境を構築する際、最初にCloud Managerコンソール上でAPIMのサーバーを追加する必要があります。その際、以下の点に注意する必要があります。

- 追加対象のAPIM上で、設定(例えばメール・サーバーの設定など)を一切実施しない
- ただし、初回ログイン時のプロファイルの更新だけは実施する必要がある

また、1台目のAPIMのクラウド・コンソールで設定した内容(例えば、LDAP設定やグループ設定など)は、2台目のAPIMにも自動的に反映されます。これは、クラスター環境下に存在するAPIMでは定期的に同期が取られるためです。ただし、mgmtコマンドでの設定内容は同期されないので各サーバー上で実施する必要があります(例えば、syslogなどの設定をする場合は注意が必要)。

#4. APIMダウン時の考慮点
クラスターに参加しているAPIMには役割があります。1台はPrimaryとして、残りはSecondary(RSS/AA)として振る舞いますが、各サーバーの役割は"ha list"コマンドを実行して確認します。

```shell-session
APIMTest01/APIConnect> ha list
Self  IP               HA    Network  Role       Runtime  FQDN
Yes   xx.xxx.xxx.xxx   Yes   Up       Primary    Up       APIMTest01.pot.ibm
No    yy.yyy.yyy.yyy   Yes   Up       RSS/AA     Up       APIMTest02.pot.ibm
```

運用手順書の作成や基盤テストの検討の際には、クラスター内でどのようにデータの更新が実施されているのか把握しておく必要があります。正常系では、以下の通りデータが更新されています。

- Primaryサーバーでのデータ更新はPrimaryサーバー上で実施され、その後、Secondaryサーバーと同期が取られる
- Secondaryサーバー上でのデータ更新はSecondaryサーバー上では実際されず、一度更新処理のリクエストをPrimaryサーバーに依頼する(その後は上と同じ)

では、どちらかのサーバーがダウンした場合、データの更新はどのように実施されるのでしょうか。Secondaryサーバーがダウンした場合、復旧後Primaryサーバーの更新内容が同期されます。問題はPrimaryサーバーがダウンした場合ですが、具体的に以下の通り更新内容が同期されます。

- Primaryサーバーがダウンして一定時間が経過した後、SecondaryサーバーがPrimaryサーバーになる
- ダウンしているサーバーが復旧するまでの間は、(新しい)Primaryサーバーがデータ更新を実施する
- ダウンしていたサーバーが復旧すると、Secondaryサーバーになり、(新しい)Primaryサーバーと同期が取られる

尚、SecondaryサーバーがPrimaryサーバーになるまでの間はPrimaryサーバーとの通信ができないため、この間はデータの更新ができないことになります。

>参考: Primaryサーバーがダウンした時のイメージ
![picture.PNG](https://qiita-image-store.s3.amazonaws.com/0/198881/5d5d3aeb-5a47-4183-bf08-44e4a3a13bfd.png)

#5. FixPack適用時の考慮点
クラスター環境下に存在するAPIMにFixPackを適用する場合、適用する順番を遵守する必要があります。

1) SecondaryサーバーすべてにFixPackを適用する(Secondaryサーバー間の適用順序は任意)
2) 1)が完了した後で、PrimaryサーバーにFixPackを適用する

という順序を守る必要があります。そのため、FixPack適用前に、"ha list"コマンドを実行して各APIMの役割(PrimaryかSecondaryか)を確認しておくことが重要です。

因みに、誤ってPrimaryサーバーからFixPackを適用してしまった場合、以下のような事象が発生します。

・PrimaryサーバーのFixPack適用は成功する
・SecondaryサーバーのRuntimeがダウンしたままになり、クラスターから強制的に離脱させられる("dissociation"という状態になる)

この状況になると、APIMの管理者に以下のようなメールが通知されます。

```shell-session
Subject: Cloud dissociation has been detected.

One or more servers have become dissociated from the cloud. This requires administrative action to resolve diverging copies of configuration data.  You can log in to IBM API Connect Console and click on the clusters tab to see more details: https://<host_name>:443/cmc
```

残念ながら、このメールを読んだだけでは何をすべきか分かりにくいのですが、以下の手順でクラスターから離脱したサーバーを復旧させます。

- Cloud Managerコンソール上で、離脱したサーバーを削除する
- "system clean apiconfig"コマンドを実行して初期化する(ネットワーク以外の設定はすべて失われるので注意)
- Cloud Managerコンソール上で、初期化したサーバーを再追加する

#6. まとめ
APIMをクラスタ構成で構築する際の考慮点をまとめました。ご紹介した内容を意識して作業に取り組むと、プロジェクトを円滑に進めることができると思います。
display:none; VS visibility:hidden; VS opacity:0;

CSSで要素を見えなくする以下の3つの指定についてです。それぞれ挙動に違いがあるのでまとめておきます。
**”領域を確保するかどうか”**と**"クリックできるか”**の違いがあることを覚えておくようにしています。

表にまとめると以下のようにそれぞれ違う挙動になります。

| スタイル       |       領域の確保 |    クリック（イベント）    |
|:-----------------|:------------------|:------------------|
| display:none;             |              × |        ×        |
| visibility:hidden;          |            ○ |       ×       |
| opacity:0;             |              ○ |        ○        |

#使い所
```
display:none;
```
完全に消えます。

```
visibility:hidden;
```
領域を確保するけどクリックすることはできない。

```
opacity:0;
```
透明になるだけで消えるわけではない。領域も確保するしクリックも出来るため誤クリックの原因になることも。(対応を後述)

##opacityプロパティの値が0の時の誤クリック対応

非表示にしていた要素をアニメショーンを使ってふわっと表示させたい時があると思います。
displayの値がnoneになっているとtransitionプロパティが効かないのでopacityを使いたいところですが、領域も確保するしクリックも出来るため誤クリックが起きてしまいます。その場合はpointer-eventsプロパティを使って対応できます。

```lang:css

.item{
 opacity: 0;
 pointer-events: none;
 transition: all 0.5s;
}
.item:hover{
 opacity: 1;
 pointer-events: auto;
}


```
Amazon ECSでHashiCorp Vaultを動かそうとしてハマった件

**問題**
Macのローカルで動作していた HashiCorp Vault のDockerイメージをAmazon ECSに持っていったら、タスクが起動停止を繰り返してしまう症状が発生した。

**環境**
Docker image / 0.8.3, <https://hub.docker.com/_/vault/>
ECSインスタンス / amzn-ami-2017.03.g-amazon-ecs-optimized (ami-21815747)


**原因と対策**
ECSインスタンスにログインして、ログを確認したところ、

```console:原因
$ docker logs <CONTAINER ID>
Error initializing core: Failed to lock memory: cannot allocate memory

This usually means that the mlock syscall is not available.
Vault uses mlock to prevent memory from being swapped to
disk. This requires root privileges as well as a machine
that supports mlock. Please enable mlock on your system or
disable Vault from using it. To disable Vault from using it,
set the `disable_mlock` configuration option in your configuration
file.
```

とのことだった。

一瞬、え？メモリ不足？と思ったのだが、
このECSインスタンスでは `mlock` が動作しないらしく、
Vaultのconfigに
`disable_mlock = 1`
を追記し、imageをECRにpushし直したら元気に動くようになった。

めでたしめでたし。
型があるtemplate class型であるかチェックするメタ関数

#例　vectorかチェックする

```cpp:main.cpp

//vectorかチェック
template<class Type>
struct is_vector : std::false_type
{};
template<class ValueType,class Alloc>
struct is_vector<std::vector<ValueType,Alloc>> : std::true_type
{};

int main()
{
	is_vector<std::vector<int>>::value; //true

	return 0;
}

```

上のように特殊化をしてやれば簡単に実装できますが、is_list,is_mapなどいちいち用意していては大変なので
テンプレートテンプレートパラメータをうけとり、まとめて特殊化してあげればよい

#is_template


```cpp:main.cpp

//TypeがTemplate型であるか
template<template <class...>class Template,class Type>
struct is_template : std::false_type
{};
template<template <class...>class Template, class... Args>
struct is_template<Template, Template<Args...>> : std::true_type
{};

int main()
{
	is_template<std::vector,std::vector<int>>::value;	//true
	is_template<std::list, std::list<int>>::value;		//true
	is_template<std::map, std::map<int,double>>::value;	//true

	return 0;
}


```

またエイリアステンプレートでラップをかけてあげてば、それぞれのメタ関数として使える

```cpp:main.cpp
template<class T>
using is_vector = is_template<std::vector, T>;

template<class T>
using is_list = is_template<std::list, T>;

template<class T>
using is_map = is_template<std::map, T>;
```
【Spring Data Jpa のやり方】


①POM.XMLにタグを追加する。

```pom.xml
	<!-- SpringBootでDataJpaを使用できる様にする設定 -->
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-data-jpa</artifactId>
	</dependency>
```


②Entityクラスを作る。

[must]@Entityをつける.これによって、Entityクラスである事を示す

[must]@Tableをつける.nameはDBのテーブルの名前.
　　　 省略した場合は、クラス名を大文字にした名前のテーブルにMappingされる
　　　 
[must]PRIMARY KEY の付いているカラムに@Idを付ける.@Idが無いと機能しない.
      無い場合はDBにPRIMARY KEYを付けるか、
	  @GeneratedValue(strategy = GenerationType.IDENTITY) を付ける。
	  これを付ければ、PRIMARY KEYを生成できる。
      DBが複合キーとなっている場合は、@javax.persistence.EmbeddedIdを使用する

[must]@Columnを付け、Mappingさせるカラム名を指定する.
　　　 省略した場合はプロパティ名を大文字にした名前のカラムへMappingされる.

```Entity.class
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

//Entityクラス = DBのtable
@Entity
@Table(name = "player")
public class Player {

	@Id
	@Column(name = "id")
	private Integer id;
	@Column(name = "name")
	private String name;
	@Column(name = "nationality")
	private String nationality;
	
//以下Getter Setter
```


③リポジトリを作成する.
  いつものクラスでなく、インターフェースで作る.


[must]クラス名の後に、以下を追記する.
					 ⬇		︎
extends JpaRepository<Player, Integer>


```Repository.class
import org.springframework.data.jpa.repository.JpaRepository;
import jp.co.rakus.football.entity.Player;

//JpaRepositoryを継承する事で、fineOne、findAll、save、deleteの4メソッドが使用
//ジェネリックスはエンティティのクラス名と、主キーの型を指定する.
public interface PlayerRepository_DataJpa extends JpaRepository<Player, Integer> {

//Sqlを書きたい場合はこの様にして書く事ができる.
//書かないでも元々用意してあるメソッドは使える.
@Query("select u from User u where u.email = :email")
User findByCustomerEmail(@Param("email")String email);

}
```


④準備できたので、後はサービスやコントローラーで使用する

```Service.class
@Service
@EnableTransactionManagement
public class PlayerService {

	@Autowired
	PlayerRepository_DataJpa playerRepository_DataJpa;
		
	public List<Player> findAll() {
		return playerRepository_DataJpa.findAll();
	}

	public void saveUserInfo(User user) {
		userRepositoryDataJpa.save(user);
	}
}
```
JavaScriptで2つのオブジェクトの配列を比較する

下記のように2つのオブジェクトの配列について、xyが同じ値のとき、dataの値を比較して、異なっていたら差分箇所を出力するとした際にArray.prototype.filterを使ってフィルタリングしたのでメモ。

```javascript:data.js
  const arr1 = [
    {
      x: 1,
      y: 1,
      data: a
    },
    {
      x: 1,
      y: 2,
      data: b
    },
    {
      x: 1,
      y: 3,
      data: c
    },
  ];

  const arr2 = [
    {
      x: 1,
      y: 1,
      data: a
    },
    {
      x: 1,
      y: 2,
      data: b
    },
    {
      x: 1,
      y: 3,
      data: d
    },
  ];
```

```javascript:filter.js
  const diff = arr1.filter(item1 => {
    const notMatch = arr2.filter(
      item2 =>
        item1 x === item2.x &&
        item1.y === item2.y &&
        item1.data !== item2.data
    });
    return notMatch.length !== 0;
  });

  if (diff.length !== 0) {
    console.info('Different!!!');
  }
```

追記、コメントでsomeのほうがいいだろという指摘があったので追記

```javascript:some.js
  const diff = arr1.some(item1 => {
    arr2.some(
      item2 =>
        item1 x === item2.x &&
        item1.y === item2.y &&
        item1.data !== item2.data
    });
  });

  if (diff) {
    console.info('Different!!!');
  }
```

ただ、判定するだけならsomeのほうがわかりやすいですね。

かなり特殊な状況ですが、思いつくまでに時間かかったのでQiitaにて供養。
Elm入門

# Elm入門
## Elm言語とは
elmとは関数型の言語で、「関数型altJS言語」なんて呼ばれたりしています。

Haskell的な文法と、厳密な関数型プログラミングでバグのないクライアントサイドアプリケーションを構築できるとされています。
また最近はやりのredux、vue.jsのVuexといった状態管理の解法は、elmに触発されて設計されています。

## Elmを始めるにあたって
いきなりelmのチュートリアルを始めるのもいいと思いますが、関数型言語に触れたとこがない方は関数型の概念から理解しないと最初はつまづきそうです。
まずはこちらが参考になると思います。
[関数型プログラミングはまず考え方から理解しよう - Qiita](https://qiita.com/stkdev/items/5c021d4e5d54d56b927c)。

特にとっつきにくい言語ではなく、海外では導入企業も増えていますし、日本の企業だとFringe81が新規事業のサービスにelmを導入しているようです。

## elmの基本文法
elmがいかに触れやすい言語であるのか、以下に記述してみようと思います。

```JS:文字
> "hello" ++ "world"
"helloworld"
```

```JS:数字
> 9 / 2
4.5

> 9 // 2
4
```

```JS:IF文
> if True then "hello" else "world"
"hello"

> if False then "hello" else "world"
"world"
```
if then else の条件付きの振る舞いには、かっこや中括弧は必要ありません。
そのため可読性も良いです。

```JS:配列
> names = [ "Alice", "Bob", "Chuck" ]
["Alice","Bob","Chuck"]

> List.isEmpty names
False

> List.length names
3
```

ざっと例をあげてみましたが、JavaScript、Python、Javaなどの言語の構造と非常に密接に対応しているため最初の学習コストは少ないと思います。

## おすすめのtutorial

私が実際に学習してみて、良いtutorialだったのが、こちらです。
基本からアプリケーションの導入までのドキュメントになっていて、丁寧でわかりやすいです。
[Elm Tutorial](https://www.elm-tutorial.org/jp/01-foundations/01-hello.html)
## 参考情報
elmのテンプレート機能の「html」 htmlモジュールには仮想DOMになっている。
- [elm tutorial](https://www.elm-tutorial.org/jp/)
AWSのSESでメールを受信してSNS経由でWEBサーバにHTTP（s）通信する

前準備
・メール受信に必要なドメインのMXレコードを設定
・メールを保存するS3バケットを作成、ポリシーを設定しておく
ポリシーは以下に書いてます。
http://docs.aws.amazon.com/ses/latest/DeveloperGuide/receiving-email-permissions.html

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowSESPuts",
            "Effect": "Allow",
            "Principal": {
                "Service": "ses.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::BUCKET-NAME/*",
            "Condition": {
                "StringEquals": {
                    "aws:Referer": "AWSACCOUNTID"
                }
            }
        }
    ]
}
```

SNSの設定
トピックを作成する
↓
Subscriptionsで、HTTP通信したいURLを設定する
↓
ARNを覚えておく

SESの設定
SESのEmail Receivingで受けるメアドを設定
↓
AddActionでS3を選択
メールを保存するbucketを選択
SNS topicで、さっき作ったSNSを設定する

ここまでで手順は終わり。
メールテスト。
受けるメアドにメールを送信して、S3にメールが入る＆サーバにアクセスが来ていたらOK。
Githubでブランチ作成からプルリク作成までを自動化する

githubにリポジトリをホスティングしている開発プロジェクトの場合のよくある開発手順

1. masterからfeatureブランチを派生 `git checkout -b feature/hoge`
2. featureブランチに空コミット `git commit --allow-empty -m "Make pull-request [ci skip]"`
3. githubにプッシュ `git push -u origin feature/hoge`
4. ブラウザでgithubを開く
5. プルリク作成

これをコマンド1発で作成できるようにしました。

# 参考記事
[GitHub の Pull Request の作成/終了に付随する作業を alias を使って楽にする ｜ Developers\.IO](https://dev.classmethod.jp/tool/github/pull-request-operation-using-alias/)

# hubのインストール
hubはgithubが提供しているコマンドラインツールです。
このツールを使ってコマンドラインからプルリクを作れるようにします。
インストールはbrewから

```
$ brew install hub
```

hubを使ってプルリクを作るには

```
$ hub pull-request 

https://github.com/example/example/pull/23
```
これでプルリクが作られました。作成後に表示されるURLがプルリクのURLになります。

# .gitconfigにエイリアス追加

gitconfigに手順をひとまとめにしたエイリアス`mkpr`を作成します。

```shell-session:.gitconfig

[alias]
	ec = commit --allow-empty -m \"Make pull-request [ci skip]\"
	mkpr = !"f() { git checkout -b $1; git ec; git push -u origin $1; open $(hub pull-request -m "$1"); }; f"
```

`ec`は空コミットのエイリアスです。 `\"Make pull-request [ci skip]\"`のコミットメッセージ部分は自由に変更してください。
`mkpr`はブランチ作成, 空コミット, プッシュ, プルリク作成を順に実行しています。最後のopenはmacの標準ブラウザを開くコマンドで、`hub pull-request`が返すプルリクのURLをブラウザで開きます。

```
$ git mkpr feature/hoge

Switched to a new branch 'feature/hoge'
[feature/hoge 47c410a] Make pull-request [ci skip]
Counting objects: 1, done.
Writing objects: 100% (1/1), 196 bytes | 196.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To github.com:example/example.git
 * [new branch]      feature/hoge -> feature/hoge
Branch feature/hoge set up to track remote branch feature/hoge from origin.
```

参考記事とはmkprのコマンドの中身を若干変えて、引数で渡した文字列`feature/hoge`をタイトルにしてプルリクを作成し、ブラウザから開くようにしています。
作成後はサマリは空状態なので、適宜ブラウザからタイトルとサマリを編集しましょう。

# もっと楽にしたい
GithubにはIssueとプルリクの[テンプレート機能](https://github.com/blog/2111-issue-and-pull-request-templates)があるので、hubコマンドからプルリク作成した場合もこのテンプレートファイルを使ってサマリ部分を記述済みにしたい。
Frontend Framework無しでComponent化を導入する

# コンポーネントとは
コンポーネントについて、いろんな説がありますが、とりあえず、例を上げさせていただきます。

## VueJSの中で、コンポーネントは
![img](https://nicholaslee119.github.io/images/vue-component.png)

## ReactJSの中で、コンポーネントは
```js

class HelloMessage extends React.Component {
    render() {
      return (
        <div>
          Hello {this.props.name}
        </div>
      );
    }
  }

  ReactDOM.render(
    <HelloMessage name="Jane" />,
    mountNode
  );
```

## Polymerの中で、コンポーネントは
```html
<dom-module id="contact-card">
    <template>
      <style>
        compA {
          font-size: 12
        }
      </style>
      <div class="compA">I am a component</div>
    </template>
    <script>
      class ContactCard extends Polymer.Element {
        static get is() { return "contact-card"; }
        static get properties() {
          return {
            starred: { type: Boolean, value: true }
          }
        }
      }
      customElements.define(ContactCard.is, ContactCard);
    </script>
</dom-module>
```

## Web componentsの公式説明は


>Web components are a set of web platform APIs that allow you to create new custom, reusable, encapsulated HTML tags to use in web pages and web apps. Custom components and widgets build on the Web Component standards, will work across modern browsers, and can be used with any JavaScript library or framework that works with HTML.

## 個人的な理解は
コンポーネント化とは、コンポーネント単位でコンポーネントに関わるHTML/JS/CSSを揃えてひとまとめにする事を言います。
ひとまとめの意味は、一つのファイルでも一つのfolderでもかまいません
 （PS：もちろん上述以外にもcustom elements/shadow DOM..等の概念が含まれます。）

# コンポーネント化のメリット
VueJS／React／AngularJS／Polymer等を使ったことがある人はコンポーネントのメリットを強く実感していると思います。

# 目下の課題

いま流行っているframeworkはコンポーネントのシステムを提供する以外にも、Data BindやVirtualDOM等の機能も提供していますが
私が適用したいのは大規模なCMSサイトであり、SEO戦略に多くリソースを割いていることから、影響範囲を絞ってのFramework導入は困難だと思います。
加えて、VirtualDOMやData Bind等は、大規模的なCMSでは有用性があまりない機能であると思います。

# Frontend Framework無しでコンポーネント化できるか
上述の課題を考慮した上で、webpackの力を借りればコンポーネント化を実現できると思います。
以下、図解になります。

![img](https://nicholaslee119.github.io/images/component-loader.png)

上記は私が作成したwebpack-component-loaderの概念設計となります。
ご覧の通り、開発環境でコンポーネント単位で切り出した部品を、該当のコンポーネントに関わるtemplate/JS/CSSを揃えて同じfolderに置きます。
開発が完了したら、loderが自動的にtemplateをbackendのtemplateのdirectoryに置きます。さらにJS/CSSをbundleしてfrontendのjsとcssのdirectoryに置きます。
このように、開発時はコンポーネント化の恩恵を受けながら、現行の本番環境の構成に影響を及ばさないことが可能となります。

# Link
github: [webpack-component-loader](https://github.com/nicholaslee119/webpack-component-loader)
スムーススクロールが'top' of undefinedとか言われてうまく動かなかった話

# この記事のターゲット
・フロントエンドむつかしい
・JavaScript実質初めて触った
・ページ内リンクでぬるぬる動くあれがやりたい
・やりたいのになんか動かない


# 注意書き
知っている方からすれば当たり前じゃんという内容でしかありません。
結論を言えば動かなかった理由は私の勉強不足でしたので、困っていない方はブラウザバックしていただいてオッケーです。


# 事の経緯
私はこれまでphpやruby、perlなどを触る機会が多く、あまりhtmlやcss、javascriptに触れる機会がありませんでした。
しかしこれではいかんと一念発起、フロントエンドの技術も触っていかねばと思い、webポートフォリオを作り上げることを目標に静的ページの作成を始めたわけでありました。

# 問題発生

見よう見まねでbootstrapなんかを使い何とか1ページ、見れるものができたところでページ内リンクを貼りたくなりました。
スーッと動いていい感じのところまで行ってくれるのいいですよね。
という事でパパッとググってhtmlの随所にこんなタグを入れ込みました。

```html
<a name="home"></ a>
```

...はい。
察した方はもうここから先を読む必要はないです。
ここまでお付き合いいただきありがとうございました。

さて、このタグを入れた事で無事ページ内リンクが動くようになりました。やったね。
ところがどっこい、あのぬるぬる動く感じを出すにはJavaScript（jQuery）を使う必要があると。
あいやわかりました。
毛も生えていない素人ですが勉強のためにやっている事です。使ってみましょう。
これまたパパッと調べて以下のようなスクリプトでいけるという事でしたので書きました。

```js
$(function() {
  $('a[href^="#"]').click(function() {
    var speed = 500;
    var href = $(this).attr("href");
    var target = $(href == "#" || href == "" ? 'html' : href);
    var position = target.offset().top;
    $('html, body').animate({scrollTop:position}, speed, 'swing');
    return false;
  });
});
```

ここではこのコードの説明は特にしません。
詳しく説明してくださっているサイトがいくつもあるのでそっちみてください。

さて、このスクリプトを書いていざスムーススクロール！
と思いきやブラウザからエラーが返されました。はて。

```
Uncaught TypeError: Cannot read property 'top' of undefined
```

どうやら`offset()`のtopが取得できていないっぽい。
何でやろかとググってみると、jQueryのバージョンによっては記述が厳しくなったとか、ブラウザが古いからだとか、`$(window).load(function(){})`の中で実行とか、色々出てきましたが一向に解決せず。


# 原因解明
3時間かかりました。ええ。
諦めてその日は寝ましたとも。

簡潔に原因を述べると、javascript側ではなくhtml側にミスがありました。
ページ内リンクのために以下のようなタグを入れ込みましたが、これが間違い。

```html
<a name="home"></ a>
```
正しくは

```html
<div id="home"></ div>
```
でした。（別にdivじゃなくてもいい。要はname属性ではなくid属性で指定するべきという話。）
どうもHTML5ではページ内リンクにname属性を使うのは非推奨（廃止？）になったらしいです。（一体何周遅れな知識なのか...）

# まとめ
完全に勉強不足でした。
あと調べ方が悪かった。
エラーメッセージだけで検索しているとこの原因はなかなか出てこなかったので...

結局のところ、最初に見つけたページ内リンクの貼り方のページが古かったわけですね。
今後は複数のサイトを見て正しい書き方をきちんと考察していきます。
Open LibertyをDockerで動かしてみる


## はじめに
WebSphere Libertyがオープンソースとなり、Open Libertyとして公開されました。DockerHubでも入手できるので試してみます。

## 前提条件
動かした環境は以下の通りです。
* MacBook Air El Capitan
* Docker v17.09

## 方法
１. DockerコマンドでOpen Libertyイメージをpullします。

```docker
docker pull openliberty/open-liberty
```
![Kobito.iR140A.png](https://qiita-image-store.s3.amazonaws.com/0/129662/3d051d51-b2f4-8bb3-de78-e2fa96928ce5.png "Kobito.iR140A.png")


２. 入手したイメージを確認します。

```docker
docker images
```
![Kobito.dn5CqU.png](https://qiita-image-store.s3.amazonaws.com/0/129662/64758878-913e-8384-aae5-fa6e2ff20ca7.png "Kobito.dn5CqU.png")


３. コンテナを起動し、プロセスを確認します。

```docker
docker run -i -t openliberty/open-liberty
```
![Kobito.9zAnmZ.png](https://qiita-image-store.s3.amazonaws.com/0/129662/92f38a23-e112-b4d6-d728-ce9c2aaa93db.png "Kobito.9zAnmZ.png")

![Kobito.W7XECv.png](https://qiita-image-store.s3.amazonaws.com/0/129662/498ffca8-6b70-ebb3-84f1-ac20f8eb26d7.png "Kobito.W7XECv.png")

Liberty v17.0.0.3がIBM J9 VMのv8.0.5.0で動いていることが確認できます。

## まとめ
Open LibertyのDockerイメージをpullしてrunするところまでを確認しました。今後はサンプルアプリを動かすなど動かし方を掘り下げていこうと思います。

## 参考
https://hub.docker.com/r/openliberty/open-liberty/
https://openliberty.io/
https://github.com/OpenLiberty/open-liberty
https://www.openliberty.io/guides/


https://developer.ibm.com/wasdev/blog/2017/09/19/liberty-open-source/
https://developer.ibm.com/wasdev/blog/2017/09/13/open-java-ee-eclipse-foundation/
https://www.ibm.com/developerworks/community/wikis/home?lang=en#!/wiki/W3142f890ea04_4b2b_b746_ac9e833c537e/page/Open%20Liberty


https://mag.osdn.jp/17/09/21/164500
https://japan.zdnet.com/article/35107550/
UI > 通知 > コメントにXXXしました > コメントやその記事にたどりつけない | UIの更新

通知が来るとする。

> コメントにXXXしました。

クリックをする。

XXXした人のページに飛ぶ。

XXXされたコメントや、コメントの元記事にたどりつくUIは用意されていない。

どういうコメントにXXXが付いたか分からない。

以下のUIは用意されている。

- コメントから
    - XXXした人のページに飛ぶUI
    - 元記事に移動 (ページをスクロールする)


### 更新
(追記 2017/11/05)
上記のようなUIでしたが、2017年11月5日現在、コメントにたどりつくように更新されていました。

XXXの開発者の方はお疲れ様です。
puppeteerを使ってスクリーンショットを撮る


PhantomJSを使った処理を作っていたら、なんかうまくいかなかったので
Googleが作っているというnode.jsからchromiumを実行するモジュール「puppeteer」を使った時のメモ
#インストール
実行環境はCentos7.3
まずはnpmコマンドでモジュールのインストールをします。

```
npm install puppeteer -g
```
このコマンドでpuppetterとchromiumがグローバルインストールされます。

しかし、これだけでは依存関係のすべてがインストールされるわけではないので、
足りないものがある場合は別途インストールする必要があります。

puppeteerがインストールされているディレクトリに移動して
依存関係の一覧と有無を確認します

```
cd node_modules/puppeteer/.local-chromium/linux-499413/chrome-linux
ldd ./chrome
```
このコマンドで出力される内容の内、not found になっているものをyum等を使ってインストールします。

インストールした後、もう一度同じようにコマンドを実行し、not found がなくなればOKです

#実行
puppeteerをrootユーザーで実行する場合は

``` test.js
puppeteer.lunch()
```
ではエラーになるので


以下のように明示的に--no-sandboxのオプションを付ける必要がある

```
puppeteer.lunch({args: ['--no-sandbox']})
```
実際に使うとこんな感じ

```screenshot.js
async function screenShot (url){
  
　var puppeteer = require("puppeteer")

  try{

    const browser = await puppeteer.launch({ args: ['--no-sandbox'], timeout: 30000 });
    const page = await browser.newPage();

    await page.goto(url);
    await page.screenshot({ "path": "path/to/png or jpg" });
    await browser.close();
    
　　console.log("OK")

  }catch(e){
    console.log(e)
  }
}
```
スクリーンショットを取ってくるサンプルです。
画面サイズの指定がないので、見切れたりするかも・・

ちなみに、puppeteerはPromiseベースなのでasync/awaitと相性がいいです。
Cognosの導入がうまくいかないパターン⑤ - Framework Managerのメタデータ・ウィザードでエラー

#エラー内容
Cognos Analytics 11.0.7@Linuxで発生しました。
データソースはDB2 11ですが、Cognos Administrationでのデータソース接続は問題ないものの、Framework Managerのメタデータ・ウィザードでテーブルを取り込もうとすると、以下のエラーとなりました。

BMT-IMP-0002 メタデータ要求を実行できませんでした。invalidDriverLocationCAF-WRN-2082 エラーが発生しました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/147246/d7ea65c6-4f4b-d894-3e29-a2a1ec9dbd80.png)

#原因

以下のフォルダーにJDBCドライバーを置いていた事が問題でした。
\# pwd
/opt/ibm/cognos/analytics/webapps/p2pd/WEB-INF/lib
\# ls | grep db2
db2jcc.jar
db2jcc4.jar
db2jcc_license_cu.jar

/opt/ibm/cognos/analytics/v5dataserver/lib などにも置いてはいけません。

/opt/ibm/cognos/analytics/drivers のみに置くようにしましょう。

/opt/ibm/cognos/analytics/webapps/p2pd/WEB-INF/lib からJDBCドライバーを削除して、Cognosを再起動すると。

しっかりとテーブルが見えるようになりました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/147246/50947e20-6e44-a4df-1239-6c8bcecd32e4.png)


ちなみに、何故 /opt/ibm/cognos/analytics/webapps/p2pd/WEB-INF/lib にドライバーを置いていたかですが、カスタム認証のJDBCSampleをセットアップするためです。
Cognos Analytics 11.0.4では、/opt/ibm/cognos/analytics/webapps/p2pd/WEB-INF/libにドライバーを置かないとカスタム認証が実装できませんでした。
SDKのreadme.txtにもその様に記載されていて、Cognos Analytics 11.0.7のreadme.txtでもその記載は変わっていないのですが、11.0.7では/opt/ibm/cognos/analytics/driversにドライバーを置くだけで問題なくカスタム認証できました。

きっとどこかで同じ事が発生すると思いますので、この情報がお役に立てばと思います。
Raspberry Pi用の無停電装置（Pi-UpTimeUPS for Raspberry Pi Zero W）

# 序
AlchemyからRaspberry Pi用の無停電装置が出たので、さっそく購入してみた。
自分の用途としては、Raspberry Piでdumpを使ってflightrader24やAPRSを運用しているので、そのための無停電装置として使用するつもりである。

# ハードウェア

![IMG_1601.jpg](https://qiita-image-store.s3.amazonaws.com/0/125657/8304372f-baba-4066-e7c8-c997a5c0cf14.jpeg)

Pi-UpTimeUPS自体は現在電池が2つついたモノが発売されているので、どちらを買うかは自分で決めて欲しい。
ちなみに、日本のamazonでも買えない事はないが、割高なので輸入した方がいいだろう。ただし、リチウム電池は別途購入しなければならないので、秋月などで別途購入して欲しい。
Raspberry Pi用の無停電装置は、このPi-UpTimeUPS以外でも数点出ているが、購入価格や設定の有無などを考えて行くと、恐らくこの製品がマストといえるだろう。
接続方法は、基本的にはGPIOの直差しして、UPSのINに電源元のUSBを刺せばお終いである。
Pi-UpTimeUPS自体は、GPIO26でUPS元の電池の容量を監視し、電池容量がある一定以下になった段階でシャットダウンコマンドを行うというようだ。つまり、元電源が落ちた段階で直ちにシャットダウンを行うわけではないということを覚えて置いた方がいいだろう。
また、Raspberry Pi ZeroでGPIO端子がないものに関してもUSBを介して接続できるが、その場合はシャットダウンコマンドなどは利用できない。
重複になるかも知れないが、利点は次の様になっている。

- 価格が安い（本体が25ドル、リチウム電池はamazonなどで1個数百円）
- 管理が簡単である（Pythonアプリ1個で簡単に管理できる）
- リチウム電池を利用するということで、電池容量にある程度余力がある
- GPIOがUPS本体にあるので、これを付けたらGPIOが使えなくなったということがない
- Raspberry PiにもRaspberry Pi Zeroにも利用できる

よく考えられた製品といえるんじゃないだろうか。

# ソフトウェアの設定
GPIOに接続した場合を前提に話を進める。
設定は簡単で、まずは`wget` コマンドを次のように利用して、シャットダウン用のアプリをダウンロードする。

```
$ wget http://alchemy-power.com/wp-content/uploads/2017/06/GPIO-shutdown-sample.zip
```

本体はPythonプログラムであるが、まずは`unzip`コマンドを利用して解凍し、次のようにPythonプログラムを動かしてみる。その際、電源元のUSBを外しておくようにする。

```
$ sudo python GPIO-shutdown-sample.py
```

このコマンドを利用すると、10秒ごとにタイムスタンプが表示されるはずだ。
電源がある程度落ちた場合、シャットダウンコマンドが適用され、Raspberry Piがシャットダウンされる。
また、10秒ごとのタイムスタンプを表示しない場合は、GPIO-shutdown-sample.pyの78行をコメントアウトする。

```
print("Time is %s " % (time.ctime()))
```

シャットアウトが確認できたら、次にこのプログラムを`cron`で管理する。
その際、/usr/local/binに置く必要があるので、次のようにする。

```
$ sudo mkdir /usr/local/bin
$ chmod 755 /usr/local/bin
$ sudo cp GPIO-crontab.py /usr/local/bin/uptime-gpio.py
$ sudo chmod 755 /usr/local/bin/uptime-gpio.py
```
設定できたら、次のように`cron`を設定する。

```
$ sudo crontab -e
```

`cron`の内容は次のように設定する。

```
*/2 * * * * python /usr/local/bin/uptime-gpio.py
```

これで、起動時にuptime-gpio.pyが起動され、電源を監視することになる。

# 結
他の無停電装置と違い、価格がかなり安く、また運用面を簡単にできるので、大変お奨めである。
また、UPS本体にGPIOが設置されているので、これを利用したらGPIOが使用できなくなるということがないのもおすすめポイントである。
Sinatra で JSON API を用意し JavaScript から利用する

## 前提

データベースに格納された残高のデータを読みだして図表を描きたい。図表は JavaScript ライブラリを利用してゴリゴリ動く感じのグラフにする。このようなニーズがあったとします。

データの流れ : RDBMS → Ruby(Sinatra) → JSON → JavaScript

JavaScript にデータを渡したいといったシチュエーションはよくあると思われるのでメモ。

## JSON API の実装

まずは Sinatra 側に GET したら JSON が返ってくる API を実装する。

参考 [Ruby]SinatraでJSONを返す
http://d.hatena.ne.jp/rightgo09_ruby/20130828/p1

```rb

get '/api/balance/show' do
  if authorization # 認証に成功したか判定
    @balances = Balance.where(uid: @user.uid) # データを DB から読み出す
    # 配列に加工
    labels = []
    data = []
    @balances.each do |balance|
      labels.push(balance.month)
      data.push(balance.data)
    end

    # sinatra/json を使ってもいいけど
    content_type :json
    {
      type: 'bar',
      data: {
        labels: labels, # ラベルの配列をあてはめる
        datasets: [{
          label: "残高",
          backgroundColor: "rgba(2,117,216,1)",
          borderColor: "rgba(2,117,216,1)",
          data: data, # 数値の配列をあてはめる
        }],
      },
      options: {
        scales: {
          xAxes: [{
            time: {
              unit: 'month'
            },
            gridLines: {
              display: false
            },
            ticks: {
              maxTicksLimit: labels.count # ラベルの個数を渡す
            }
          }],
          yAxes: [{
            ticks: {
              min: 0,
              max: data.max, # データの最大値を渡す
              maxTicksLimit: data.count # データの個数を渡す
            },
            gridLines: {
              display: true
            }
          }],
        },
        legend: {
          display: false
        }
      }
    }.to_json # to_json で返せば JSON データを返却できる
  end
end
```
こんな感じで JSON API を作っておく。
JSON 全体をあらかじめ Ruby で前処理しておくのが楽ちん。

## JavaScript で JSON を利用する

まずは JavaScript のライブラリを選定。

Chart.js
http://www.chartjs.org/

こいつを組み込んだら、あとは JSON API を叩いて Chart.js に渡すところだけ書いてあげれば良い。

```js

function getBalance() {
  var data = null
  var req = new XMLHttpRequest();
  req.open("GET", "/api/balance/show", false);
  req.send(null);
  if(req.readyState == 4 && req.status == 200) {
      data = req.responseText; // JSON API の戻りを data に格納
  };
  return JSON.parse(data) // data を返却する
}
var ctx = document.getElementById("BalanceChart"); // DOM を指定
var balanceChart = new Chart(ctx, getBalance()); // Bar Chart のデータとして getBalance 関数の戻り値の JSON を利用
```

## 結果

![Screenshot from 2017-10-18 14-18-00.png](https://qiita-image-store.s3.amazonaws.com/0/38501/595bf24c-5c61-bfb0-b7d0-8bc3152416ba.png)

できました。

あとはこの要領で JavaScript ライブラリを駆使してデータの可視化をガンガンおこなえますから便利ですね。

おわりです。
PythonワンライナーでJSONの要素を出力する

こういうJSONスキーマが`test.json`というファイルにストアされていると仮定する。

```json
{
    "title": "Person",
    "type": "object",
    "properties": {
        "firstName": {
            "type": "string"
        },
        "lastName": {
            "type": "string"
        }
    }
}
```

`title`というKeyの要素を取得する場合:

```shell-session
$ python -c "import json; print(json.load(open('test.json','r')).get('title'))"
Person
```

`properties`というKeyの要素を取得する場合:

```shell-session
$ python -c "import json; print(json.load(open('test.json','r')).get('properties'))"
{u'lastName': {u'type': u'string'}, u'firstName': {u'type': u'string'}}
```

なお、ここでは Python 2.7 における実行結果を記した。
複数のサブミットボタンでアクションを変える方法

```
<form>
  <button onClick="form.action='search/';return true">SEARCH</button>
  <button onClick="form.action='csv/';return true">CSV</button>
</form>
```
各ボタンがクリックされた時にフォームのactionを指定のものに変えるような処理。
【iTerm2】キーボードでスクロールする方法

毎回、
`cat honoka`
とか
`cat maki`
とかしたあとにトラックパッドやマウスまで手を伸ばすのが面倒だったりします。

で、キーボードからスクロールアップ、ダウンする方法ですが、

cmd + ↑ or ↓
でいけます。

cmd + pageUp or pageDown
で、１ページまるごとスクロールも可能です。

もちろんHHKでも使えます。
幸せいっぱいですね。
rails5のフォントファイルの読み込み方が調べても分かりづらかったのでわかりやすく説明してみるよ。

#下準備

まず、好きなフォントファイル（ttfファイル、woffファイル、otfファイル等）をダウンロードします。

次に、app/assetsの中に、fontsという（**フォルダ**）を作ります

その中に、ダウンロードしたファイルを入れます。
ここまでで下準備はOKです。

#定義

まず、適応したいcssファイルを開いてください。
今回は、ページ全体に適応させたいので、application.cssに適応していきます。

一番最初に、src:font-urlで読み込みたいファイルを指定します。/や../などは入れないでください。

```css:application.css
 @font-face{
   src: font-url('font-file.ttf') format('truetype');
 }
```
@font-faceは一体何かというと、プログラミングの経験があるならfont用の関数だと思って貰えばいいと想います。つまり外から呼び出さないと動かすことができません。

次に、fontを呼び出すための（変数）を準備します。font-faceにおける変数は何になるかというと

```css:application.css
 @font-face{
   font-family: "hoge"
   src: font-url('font-file.ttf') format('truetype');
 }
```

追加されたところを見ていただければわかる通り、この(font-family: "hoge")の部分が変数の（**宣言**）になっています。何を宣言してもいいので、好きな変数を決めましょう。

**変数とは**：様々な値を保存しておくための箱というイメージで合っていると思います。変数についての詳しい記事は[箱(変数)の中身はなんだろう？](https://qiita.com/GrimmMarchen/items/3c5f48823153201d176a)を参照してください。

#適応

最後に、fontを使いたい場所に適応していきます。ここからはいつもと同じ流れでfont:familyを使えるため特に難しいところはないと思います。

例えば、body全体に適応したかったら

```css:application.css
 @font-face{
   font-family: "hoge"
   src: font-url('font-file.ttf') format('truetype');
 }

body{
  font-family: 'hoge';
}
```

このようにすれば適応できるようになります。また、例えば部分的に見出しだけに適応したかった場合は

```css:application.css
 @font-face{
   font-family: "hoge"
   src: font-url('font-file.ttf') format('truetype');
 }

body{
  font-family: serif;
}
h1{
  color:gray;
  font-family: "hoge";
}
```

このようにすれば適応することができます！

なお、@font-faceの中ではフォント関係の定義は一括して設定することもできるので、予めフォントの文字を太めにし、フォントのスタイルをitalicにしたかったら


```css:application.css
 @font-face{
   font-family: "hoge"
   src: font-url('font-file.ttf') format('truetype');
   font-style:italic;
   font-weight:bold;
 }
```

このようにまとめて指定しておくことも可能になります！

細かい部分についてはいろいろ触りながら感覚を掴んでみてくださいね。

#まとめ

今回は、私も相当頭を悩ませてしまった@font-faceの使い方と、実際のファイルの読み込み方をできるだけわかりやすく説明してみました。

railsの基礎をある程度抑えられていれば、この記事を読みながら作業を進められると思います！

また、もし間違っているところ等ありましたら遠慮なくコメントで教えてくださいね。
【 AWS 】 Lambda関数を作成する方法 ~S3へのファイルアップロードをトリガーにログ出力編~

# はじめに
Lamba関数を作成しようといろいろ調べてみたが、
GUIのアップデートも早く、現状と同様の画面で作成している手順が見当たらなかったので、
自分の備忘録も含めて、Qiita記事に書き残しておくことにします。

# 今回実現したいこと

 __トリガー : <font color="gold">S3バケットにファイルがアップロードされる</font>__
__処理内容 : <font color="orangered">オブジェクトキーを含めたファイルパスをログに出力</font>__

# 設定方法
## __1. AWS Lambda設定画面を開き、関数の作成ボタンを押下。__

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/263899b6-8ae2-c81c-6929-28723e8bca82.png)

## __2. 「一から作成」ボタンを押下__

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/2d25b1f0-ed62-3b51-5cd5-a8665e6a5747.png)

## __3. 「カスタムロールの作成」を選択__

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/1abc2e2b-7215-b658-6cab-b173b3b7d489.png)

## __4. カスタムロールを作成__
3.の操作後、新しいウィンドウで、カスタムロール作成画面が表示されるので、何も設定を変えず作成を行う。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/ddb67367-d4c2-c8cc-f135-b0117831e612.png)


## __5. Lamda関数の基本情報を入力__

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/ac6a7bbc-7825-2fe7-0a15-af3a06a4eba8.png)

実行ロールについては、既存のロールを選択し、先ほど作成したロールを選択する。

## __6. Lamda関数が生成されました__

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/d34b2dda-6f46-f971-37e6-578ff12871c3.png)


トリガーが設定されていないので、設定を行います。

## __7. トリガーの設定__

[トリガー]タブの「トリガーを追加」ボタンを押下

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/0f2d6e95-aad0-c1d4-b299-4353c66d33c5.png)


下記、詳細設定になります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/4985be74-235e-8e74-2c2e-04738df2da55.png)

バケット欄に対象となるバケット名を指定し、「トリガーの有効化」設定を行います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/593decd7-87f7-217b-d734-fe410dd2f6f9.png)

## __9. 実行ソースコードの修正__

とりあえず動いていることを確認したいので、
アップロードされたら、バケット名とオブジェクトキーを出力するといった簡易なソースコードを用意します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/3f615e8f-0abe-64d2-f069-b9864bf8abd1.png)



```index.js

console.log('Loading function');

exports.handler = function(event, context) {
    var Bucket = event.Records[0].s3.bucket.name;
    var ObjKey = event.Records[0].s3.object.key;
    var FilePath = Bucket + '/' + ObjKey;
    console.log('BucketName : ' + Bucket);
    console.log('ObjKey : ' + ObjKey);
    console.log('FilePath : ' + FilePath);
};

```

「 Ctrl + S 」で保存し、指定のS3バケットにファイルをアップロードしてみてください。

## __10. ログ出力の確認__

ログの確認は、 [モニタリング] タブの中にある、「CloudWatchのログを表示」というボタンを押下し、
遷移したページにて確認することができます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/ff3ef754-a101-753a-cb9e-b6ac73ef278f.png)

一覧が表示される。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/23f4ccfc-a2cd-4834-c233-72ad2342b15f.png)

ログ出力中身確認。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/8d7be9af-e55a-143f-d8ce-361e43d1b384.png)

## 無事、動作確認することができました。

とにかく動作検証なので、動くところまで、
必要な情報に関しては、今後随時更新していこうと思います。
最後までお読みいただき、ありがとうございました！
CloudGarage メールサーバ構築したのにコケた話。

# はじめに
これはメールサーバ構築自体の話ではないです。クラウドでサーバ構築した時にコケたポイント。既知の問題のようですが。メモ程度に
### 前提環境
* 利用クラウド：CloudGarage
* sshホスト:Debian9
* sshクライアント：Bash on Ubuntu on Windows10
* apache2.4
* postfix
* dovecot
* 取得ドメイン：hoge.com と仮定
* Gmailに来たメールのドメイン：fuga.novalocalと仮定  

## 何がどうしてこうなった？
1. CloudGarageさんのクラウドをお借りしたので開発用に利用
2. 予め用意されていたDebian9のイメージを利用してインストール。apache2.4(今回関係なし) postfix dovecot という極めて標準的な環境を構築しました。
3. httpサーバ構築が完了後、メールサーバ構築をし、Gmailのアドレスにテストメールを送信。
4. 自分の取得したドメインでは無いところからメールが届く  
というながれ。  

***  

## 本当の悪はどこにある？
ドメインがおかしい、と言ったときに見るポイントは多いと思うのですが…  
* DNSサーバへの登録は正しいのか？
* ローカル内で解決できているのか？(localhostなどへの送信時にどうなるのか)
* はたまた、サーバソフトは正しく設定されていて、正常に作動しているのか？

といったところになるかと思います。  

***  

## 確認でやったこと

1. ドメインの名前解決はできているか？  
→apache正常起動確認後、Windowsのブラウザから取得ドメインでアクセスできる。
2. サーバソフトの設定は正しいか？  
→postfix,dovecotともに、syntax errorなく正常稼働
3. localhost宛にメールを送る
4. fuga.novalocalからメールが来る←!?  
ここで、「おいおいおい、なんじゃこれは…」と。
/etc/postfix/main.cfには 

```
mydomain = hoge.com
myhostname = hoge.com
myorigin = $mydomain
```

と書かれている。

(ﾟдﾟ)ﾊｯ この`fuga.novalocal`のfugaは既視感がある。何を隠そう自分でインスタンスを立てた際のホスト名。ならば
5. `/etc/hosts` をいじるまで。
`127.0.0.1 fuga.novalocal fuga `を
`127.0.0.1 hoge.com fuga.novalocal fuga`に変更し保存。  
メールをGmailに再送し、確認

ｷﾀ━━━━(ﾟ∀ﾟ)━━━━!!
メールは登録したドメインでやってきた。  


## これで終わりだと思ったら大間違いだった

実はここからが本題。実はこの`/etc/hosts`の変更、インスタンス再起動で失効する。ﾅﾝﾃｺｯﾀ／(^o^)＼  
Twitterに書き込んだところこのような返答が…
<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="ja" dir="ltr">OpenStack の環境では　cloud-init という物を使用して設定しているようです。 こちらのインスタンスで確認できたのでこのファイルで設定されてるかと思います。<br>カスタムすればいけそうです。<a href="https://t.co/X0mMb104uW">https://t.co/X0mMb104uW</a> <a href="https://t.co/TYmYc5vise">pic.twitter.com/TYmYc5vise</a></p>&mdash; FoxBoxsnet (@FoxBoxsnet) <a href="https://twitter.com/FoxBoxsnet/status/920480448886665216?ref_src=twsrc%5Etfw">October 18, 2017</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>



実際に`/etc/hosts`を開いたときに
![キャプチャ77.PNG](https://qiita-image-store.s3.amazonaws.com/0/208031/c15ddcaa-7169-968b-7209-b9e11f25eeb5.png)
なぁんてかいてある。  
要するに、`/etc/hosts`は起動時に `/etc/cloud/template/hosts.debian.tmpl`から読み込まれているのである。  
よって、変更が必要な際は、`/etc/cloud/template/hosts.debian.tmpl`を書き換えないといけない。  
でこれを開いて`127.0.0.1 hoge.com fuga.novalocal fuga`と追記。

これで再起動でも反映される。やったね！！

---

## 追記
CloudGarageさんも対応してくださり、FAQが追加されています。
こちらの方法でも回避できるようですのでご確認ください。  

[CloudGarage 公式FAQ](https://cloudgarage.jp/faq/server/#25)

---

ご覧いただきありがとうございました。  

### Thanks
* CloudGarage 様 (Twitter: @CloudGarage_PR)
* FoxBoxsnet 様 (Twitter： @FoxBoxsnet )
リストの中にある複数の辞書を集計&ソートする


以下のような複数の辞書を持つリストを

```python:
base_list = [{'item': 'いちご', 'count': 100},
             {'item': 'りんご', 'count': 30},
             {'item': 'みかん', 'count': 140},
             {'item': 'みかん', 'count': 130},
             {'item': 'りんご', 'count': 10},
             {'item': 'いちご', 'count': 50},
             {'item': 'いちご', 'count': 40}]
```

以下のようにitemをキーとして集計し、countの値をキーにソートしたい時

```python:
result_list = [{'item': 'みかん', 'count': 270},
               {'item': 'いちご', 'count':190},
               {'item': 'りんご', 'count': 40}]
```

collectionsからdefaultdictとCounterを使って集計、operatorからitemgetterを使ってソートすることによってやれました

```python:
from collections import defaultdict, Counter
from operator import itemgetter

base_list = [{'item': 'いちご', 'count': 100},
             {'item': 'りんご', 'count': 30},
             {'item': 'みかん', 'count': 140},
             {'item': 'みかん', 'count': 130},
             {'item': 'りんご', 'count': 10},
             {'item': 'いちご', 'count': 50},
             {'item': 'いちご', 'count': 40}]

count_list = defaultdict(Counter)

for base_dict in base_list:
    counts = Counter({key: value for key, value in base_dict.items() if key not in ('item')})
    count_list[base_dict['item']] += counts

summary_list = [dict(value, item=key) for key, value in count_list.items()]

result_list = sorted(summary_list, key=itemgetter('count'), reverse=True)
```
App Storeへのアップロードで「This action could not be completed. Try again. (-22421) 」が出て困ったら

# 現象
App Storeへのアップロードの際に、
「Upload to App Store」を押下し暫く待つと、
以下のように表示され、何度トライしても改善されなかった。

> This action could not be completed. Try again. (-22421)

# 対処法
Xcodeを再起動して再挑戦すると、
以下のように表示され、無事完了した。

> Upload Successful

偶然そのタイミングで解消しただけかもしれませんが、
端末再起動や再アーカイブの前にお試しください。
[SpreadsheetGear]ウィンドウ枠の固定をしている時のセル位置の取得

```csharp
SpreadsheetGear.IRange range = cells["F10"];
double x, y;
if (worksheet.WindowInfo.FreezePanes) {		// ウィンドウ枠の固定実行時
	RangeLocationFlags rangeLocationFlags;
	var splitRows = worksheet.WindowInfo.SplitRows;
	var splitColumns = worksheet.WindowInfo.SplitColumns;
	
	if (splitRows > 0 && splitColumns > 0) {  // 4分割
		// セルが4分割のどこにいるか
		if (splitRows - range.Row > 0 && splitColumns - range.Column > 0) {
			rangeLocationFlags = RangeLocationFlags.Pane1;
		} else if (splitRows - range.Row > 0) {
			rangeLocationFlags = RangeLocationFlags.Pane2;
		} else if (splitColumns - range.Column > 0) {
			rangeLocationFlags = RangeLocationFlags.Pane3;
		} else {
			rangeLocationFlags = RangeLocationFlags.Pane4;
		}
	} else {  // 2分割
		if (splitRows - range.Row > 0 || splitColumns - range.Column > 0) {
			rangeLocationFlags = RangeLocationFlags.Pane1;
		} else {
			rangeLocationFlags = RangeLocationFlags.Pane2;
		}
	}
	
	// セル位置取得
	this.RangeToLocation(range.Row, range.Column, out x, out y, rangeLocationFlags);
} else {	
	// セル位置取得
	this.RangeToLocation(range.Row, range.Column, out x, out y);
}

```
CordovaでiOSのDeployment Targetを指定する方法

CorodvaでiOSアプリをビルドした時に、XcodeでDeployment Targetを必ず指定していたけど、これは面倒くさいと思って調べたらちゃんとあったのでメモ。ググっても少し探しづらかった。

```xml:config.xml
...
    <preference name="deployment-target" value="10.1" />
...
```

これでいちいちXcodeでDeployment Targetのバージョンを指定しなくても済みます。
.NET Core に関するメモ (2017年10月)

まとまってるのがあまりなかったので.....
.NET Core 使う際の自分用メモ
現在の最新は.Net Core 2.0
## インストール
1. Windwos  
ダウンロードしてインストールするだけ  
<https://www.microsoft.com/net/core#windowscmd>
2. Ubuntu  
パッケージの追加  
`curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg`  
`sudo mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg`  
インストールはUbuntuのバージョンごとに微妙に違う  
Ubuntu 17.04  
`sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-zesty-prod zesty main" > /etc/apt/sources.list.d/dotnetdev.list'`  
Ubuntu 16.04  
`sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-xenial-prod xenial main" > /etc/apt/sources.list.d/dotnetdev.list'`  
Ubuntu 14.04  
`sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-trusty-prod trusty main" > /etc/apt/sources.list.d/dotnetdev.list'`  
あとはいつも通り  
`sudo apt-get update`  
`sudo apt-get install dotnet-sdk-2.0.0`

## 新規プロジェクト/ファイルの作成
1. Console Application  
`dotnet new console -o hogehoge`
2. Class library  
`dotnet new classlib -o hogehoge`
3. Unit Test Project  
`dotnet new mstest -o hogehoge`
4. xUnit Test Project  
`dotnet new xunit -o hogehoge`
5. ASP.NET Core Empty  
`dotnet new web -o hogehoge`
6. ASP.NET Core Web App (Model-View-Controller)  
`dotnet new mvc -o hogehoge`
7. ASP.NET Core Web App  
`dotnet new razor -o hogehoge`
8. ASP.NET Core with Angular  
`dotnet new angular -o hogehoge`
9. ASP.NET Core with React.js  
`dotnet new react -o hogehoge`
10. ASP.NET Core with React.js and Redux  
`dotnet new reactredux -o hogehoge`
11. ASP.NET Core Web API  
`dotnet new webapi -o hogehoge`
12. global.json file  
`dotnet new globaljson -o hogehoge`
13. Nuget Config  
`dotnet new nugetconfig -o hogehoge`
14. Web Config  
`dotnet new webconfig -o hogehoge`
15. Solution File  
`dotnet new sln -o hogehoge`
16. Razor Page  
`dotnet new page -o hogehoge`
17. MVC ViewImports  
`dotnet new viewimports -o hogehoge`
18. MVC ViewStart  
`dotnet new viewstart -o hogehoge`

## パッケージの追加(Nugetなど)  
`dotnet add package hogehoge`
## 依存ファイルの復元（反映？）
Configファイル書き直した場合などに
`dotnet restore`
## 起動  
`dotnet run`

## まとめ
.NetCore に限らないけど困ったら`-h`すればなんとかなったりする。
OSX Sierra に Docker CE とDocker Toolbox 入れてしまった。

#結論「Docker CE」 と 「Docker Toolbox」は2つはいらん

ちょっと手違いでというか、macにもdocker入れちゃおうと思い立ち

https://www.docker.com/docker-mac
から「Docker CE」インストール

調べると「Docker Toolbox」というのもあるのでこれも入れとくかという事でインストーラを落としてインストールしようとすると、インストールが止まって動かんので、ムニョムニョネットさまようと、brewでインストールができるらしいと...
早速そんなこんなで入れて見たけど。

Toolboxの[Docker Quickstart Termina]で立ち上げてコンポーネントやインストールしたものと,
マック標準のターミナルで立ち上げてつくったコンポーネントやイメージはどうも違うところに保存されているらしいことに気づく。

docker自体は同じ/usr/local/bin下をみてるし環境変数が違うと疑い

###[Docker Quickstart Termina]では
DOCKER_HOST=tcp://192.168.99.100:2376
NO_PROXY=192.168.99.100
DOCKER_MACHINE_NAME=default
DOCKER_TLS_VERIFY=1
DOCKER_CERT_PATH=/Users/[ユーザーアカウント]/.docker/machine/machines/default

これが追加されるみたい。
Docker Toolbox (legacy)
らしいので

##Docker Toolboxは削除
https://docs.docker.com/toolbox/toolbox_install_mac/#how-to-uninstall-toolbox


でページ通りに削除したのは良いのだが
[Docker CE]でリンク貼られてたらしい/usr/local/bin下がなくなったので
そのままでは使えず。
ln使っても良かったんだけど
メニューバーのDockerアイコンから
[Prefarence]>[Reset]タブの画面の[Reset to factory default]ボタンを
押して見た！
ら、スッキリ使えるようになりました！
※イメージやコンポーネントのデータも綺麗さっぱりなくなります。入り用なものはDocker Hubへお供えしておくのが吉です。
CloudWatchの料金が高い



同僚に「CloudWatchの料金高くね？」と指摘される
Slack料金通知画面
![image.png](https://qiita-image-store.s3.amazonaws.com/0/57350/47110ad0-5819-34ed-a515-27298f4aeab2.png)

なんか高い！
Billingを確認。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/57350/9b7edb9d-6371-a1bf-e3c1-32fbf1e1521d.png)

どうやら詳細モニタリングを1分間にしていたからっぽい

EC2画面でとりあえず全て無効化する。5分間隔だと無料なんですね。
http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/using-cloudwatch-new.html

![image.png](https://qiita-image-store.s3.amazonaws.com/0/57350/0c1ee01c-7dc7-7e58-92be-42b4e0f499c6.png)

あとは見守るのみ