OmniAICreator/Qiita-1.07M huggingface dataset:
Raspberry Pi3で日本語表示/入力

# はじめに
[Raspberry Piのセットアップ ? ローカル環境編]([1])でインターネット接続まで確認しました。
しかし、日本語の表記が四角で表示されていました。
このエントリーでは日本語表示の文字化けを直す流れをまとめておきます。

# 日本語環境を設定する

日本語フォントのインストール
> $ sudo apt-get install fonts-vlgothic

日本語入力するためのソフトをインストール(iBus/uim/SCIM.. など色々ある)
> $ sudo apt-get install ibus-anthy

日本語表示するためのソフトをインストール
> $ sudo apt-get install jfbterm

MENU -> Raspberry Pi Configuration -> Localisation -> Set Locale... を以下のように変更
![raspi-config-locale-jp.png](https://qiita-image-store.s3.amazonaws.com/0/112253/7a9cd707-2180-f91f-6015-7aee6b5bc82a.png)

再起動して日本語化完了

# 端末エミュ(ターミナル)まで日本語になる問題について

上記の設定を行うとターミナルまで日本語化されるようになりました。
個人的にはターミナルだけは英語で表記のままであって欲しいのでviを使って.bashrcの終端に以下の一文を追加して再起動する。

> export LANG=en_US

viの使い方は、[viエディタの使い方]([2])を参照する。
viが分からない場合は、ファイルマネージャー -> 表示(V) -> 隠しファイルを表示する(W) を選択して、.bashrcを表示して直接クリックして立ち上げるとメモアプリから.bashrcが立ち上がるのでこちらで編集する(終わったら非表示にしよう)

# ファイルマネージャーに残った日本語のフォルダ共問題について

ファイルマネージャーを見ると、「画像」やら「ダウンロード」やら日本語のフォルダが残っていたりする。
GUIしか使わない場合は特に問題ないが英語表記の場合、ターミナルから見るとフォルダ名が「？？？？？」と表示される。

直し方は以下のコマンドを打つ

> $ LANG=C
> $ xdg-user-dirs-gtk-update

しかし何故か自分の環境だとxdg-user-dirs-gtk-updateと言うコマンドが無いよって言われる
以下の二つ方法でインストールしてみたがうまくいかなかった

> $ sudo aptitude install xdg-user-dirs-gtk
> Couldn't find any package whose name or description matched

> $ sudo apt-get install xdg-user-dirs-gtk
> E: Unable to locate package xdg-usr-dirs-gtk

なのでxdg-user-dirs-gtkをインストールするのはあきらめ以下のコマンドを打つ

> $ LANG=C xdg-user-dirs-update --force

そうしたら自動的にファイルマネージャー下の日本語ファイルを変換してくれました。
日本語のファイルはそのまま残っているからrmdirコマンドで削除して行こう。
名称変更後のアイコンが独自のものから無機質なものに変わってショックを受けましたが、再起動すると元に戻りました。


[1]: https://tool-lab.com/make/raspberrypi-startup-7/
[2]: http://www.inex.co.jp/rasbpi/rasb10-05.html
Ruby on RailsでMySQLのパスワードが弾かれる時の対処法

#本記事の対象者
こちらのエラーでハマった方：Access denied for user 'root'@'localhost'
#RailsでMySQLを使う手順

`$ rails new hoge-app -d mysql`

Gemfileに以下を記述
`gem 'mysql2'`

`$ bundle install`
`$ bundle exec rake db:create`

ここで、こちらのエラー
`ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)`

#原因
以前MySQLをダウンロードした際にパスワードを指定したため、nullパスワードが受け付けられない状態になっていた

#解決策
config/database.ymlのpassword欄に改めてパスワードを再設定する
（このディレクトリ下以外のパスワードも上書き設定される事に注意）
Luigi で Target に save() や load() メソッドをつけるとめっちゃ便利

タイトルで言いたいことは終わり、以上！

……というのも何なので少し実例を交えて。

使ったことがある方であればご存知の通り、ワークフローマネージャ Luigi ではあるタスクによって生成されるデータを抽象化して `Target` の継承クラスとして扱います。とりあえずこいつは `exists()` メソッドを実装してすでに存在しているかどうかが確認できれば機能します。
例えばローカルファイルであれば `LocalTarget` を使う訳ですが、とりあえずチュートリアルに従って書くと次のようになります。

```python
from luigi import Task, ExternalTask, LocalTarget
import pandas as pd


class RawFile(ExternalTask):

    def output(self):
        return LocalTarget('path/to/file.csv')


class Aggregation(Task):

    def requires(self):
        yield RawFile()

    def run(self):
        df = pd.read_csv(self.input()[0], sep='\t', parse_dates=[7, 8], encoding='cp932')
        ...

```

さてさて……あ、ここで `RawFile` に依存する何か別のタスクが出てきてしまった。ということを考えましょう。徐にこんなコードを書き始める訳ですが……

```Python
class Plot(Task):

    def requires(self):
        yield RawFile()

    def run(self):
        df = pd.read_csv(
```


ちょっと待って。あなたは自分が関わっているすべてのプロジェクトについて、CSV ファイルのパーサに渡すべき適切なオプションをちゃんと覚えていますか？　**私は覚えていません。**もっと言えば毎回オプションを書きたいですか。私は**断じて**何回も書きたくありません。
せっかく Luigi が Target を元データのパスなんかを抽象化してくれているのに、これははっきり言ってダルいです。そうです、**読み込みも抽象化してしまえば良い**んです。

```Python
from luigi import Task, ExternalTask, LocalTarget
import pandas as pd


class RawFileTarget(LocalTarget):

    path = 'path/to/file.csv'

    def __init__(self):
        super(RawFileTarget, self).__init__(path)

    def load(self):
        return pd.read_csv(self.fn, sep='\t', parse_dates=[7, 8], encoding='cp932')

class RawFile(ExternalTask):

    def output(self):
        return RawFileTarget()
```

というように `load()` を定義した `Target` を定義してやりましょう。

そうすれば、どの依存タスクも

```Python
class Aggregation(Task):

    def requires(self):
        yield RawFile()

    def run(self):
        df = self.input()[0].load()
        ...


class Plot(Task):

    def requires(self):
        yield RawFile()

    def run(self):
        df = self.input()[0].load()
        ...

```

とスッキリしますね。後からデータハンドリングの担当者に「ごっめーん、以前渡されたアレ、ちょっと間違えちゃっててさ……」などということばとともにシレッと仕様の違う CSV ファイルを渡されようが、何を勘違いしたか渡されたファイルが Excel になっていようが、`RawFileTarget.load()` を書き換えれば済む話です。ハッピー！

タイトルに書いてあるとおり `load()` に対応するようにして `save()` を書いてやるとまたハッピーなのですが、コード例なんかは割愛します。
Thonny(Python/IDE)を使ってみた

# はじめに

最近 Raspberry Pi3を購入してRaspbian を導入しました。
購入したものの目的があった訳ではないので、とりあえず今流行りの Python の基本を学んでみようと思い
.pyファイルを作って開いて見たところThonnyとか言うアプリが立ち上がりました。

何これ？と思って調べるとPython用のIDEらしくLinuxはもとよりMacやWindowsでも使えるみたい。
何より説明が不要なくらいシンプル。
試しにWindowsにもインストールして使ってみました。

# 公式サイト
[Thonny][1]

# 特徴
+ pythonが同梱されているのですぐ使える(既に入れているバージョンのPythonも使える)
+ ステップ実行が可能
+ 変数の一覧で中身を確認できる
+ シンタックスエラーも分かりやすく警告してくれる
+ コードの補完もしてくれる
+ 外部プラグインが利用可能

# 不満
+ ステップ実行は出来るが必ずトップから順次実行するのがやだ(ブレークポイントが無い)
+ 変数のウォッチがリアルタイムで見れない(処理完了時の値を表示しっぱなし)
+ インストール画面がなんかウィルス臭い(笑)

なので巨大な規模のプログラムには使えません。
しかし練習用には凄く向いています。
Thonnyを一言で表すなら初心者向けのPython統合開発環境

Python用のIDEは沢山ありますが、まずこちらを使ってみて物足りなくなったらPyScripterなどに移行する事をおすすめします。

# パッケージの導入の仕方
Pythonで書かれたパッケージソフトウェアをインストール・管理するために
pipと言うパッケージ管理システムを導入する必要がありますが
pip は Python 3.4 以降では Python 本体に同梱されているのですぐに使う事が出来ます。


試しにHTTPリクエストを簡単に扱うことができるRequestsパッケージを導入してみます。

+ `Tools -> Open system shell...`　を開く
+ `pip install requests` と打ってRequestパッケージを導入
+ `Tools -> Manage Packages`を確認してrequestがあるかどうか確認する


~~コマンドラインで以下の設定をします~~

~~コマンドプロンプトを立ち上げてThonnyをインストールしているパスに移動します。~~
`C:\>cd C:\Users\[User名]\AppData\Local\Programs\Thonny\`
![564.PNG](https://qiita-image-store.s3.amazonaws.com/0/112253/3144a566-8b76-6bfa-2e2b-eb070a4cc607.png)


~~`python -m pip install requests`を打ちます。~~
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/112253/48f0c446-dc0c-51dc-68c3-40fcc2506cf3.png)~~


WindowsのThonnyは`C:\Users\[user-folder]\.thonny\BundledPython36`を参照しているみたいです。



# メソッドの補完
Ctrl + Space もしくは TABキーで補完ができます。

TABはタブ機能に割り当てたいのだけどこれはデフォなのかな？


[1]: http://thonny.org/
AzureのストレージにJavaでアップロードとダウンロードメモ

#はじめに
AzureのストレージにJavaでアップロードと、
ダウンロードするメモです。

詳細は調査して、追記していく予定です。

#jarのｲﾝｽﾄｰﾙ(Maven)
```xml:pom.xml
    <dependency>
	    <groupId>com.microsoft.azure</groupId>
	    <artifactId>azure-storage</artifactId>
	    <version>5.5.0</version>
	</dependency>
```

#認証定数の定義
```java:java
	public static final String storageConnectionString = "DefaultEndpointsProtocol=http;" +
			"AccountName=[AccountName];" +
			"AccountKey=[AcountKey]";
```

#アップロード

```java:java
    // ｱｯﾌﾟﾛｰﾄﾞ処理
    private static void upload() throws Exception{
    	CloudBlobContainer container = auth();

    	// ｱｯﾌﾟﾛｰﾄﾞ処理
    	File file = new File("[アップロードファイルパス]");
    	FileInputStream fis = new FileInputStream(file);
    	CloudBlockBlob blockBlob = container.getBlockBlobReference(file.getName());
    	blockBlob.upload(fis, file.length());

    	fis.close();
    }
```

#ダウンロード
```java:java
    // ﾀﾞｳﾝﾛｰﾄﾞ処理
    private static void download() throws Exception{
    	CloudBlobContainer container = auth();

    	// ﾀﾞｳﾝﾛｰﾄﾞ処理
    	String uploadName = "[ダウンロードファイル名]";
    	CloudBlockBlob blockBlob = container.getBlockBlobReference(uploadName);

    	String downloadPath = "[ダウンロードファイルパス]";
    	FileOutputStream fos = new FileOutputStream(new File(downloadPath));
    	blockBlob.download(fos);

    	fos.close();
    }
```

#proxy環境で実行する場合
このまま実行するとタイムアウトになりますので、
jvmにproxyを設定する必要があります。
下記のパラメータを指定して、実行しましょう。

```cmd:オプション
-Dhttp.proxyHost=[proxyHost] -Dhttp.proxyPort=[proxyPort]
```
Ubuntu に npm をインストールする


Ubuntu 14.04 にnpmをインストールしようとしたところ、時間を要したので情報を整理しておく。

以下のコマンドを実行したところエラーになった。
```
sudo apt-get install nodejs
```
マニュアル[Installing Node.js via package manager](https://nodejs.org/en/download/package-manager/ "npm")にはUbuntuに導入する手順が記載されている。その手順に従う。

まずインストールに失敗した nodejs を削除する。
```
sudo apt-get remove --purge nodejs
```

次にマニュアルに記載された手順に従う。
```
sudo apt-get install curl
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
sudo apt-get install -y nodejs
```

その後、最新のnpmをインストールする
```
sudo npm install npm@latest -g
```

以上。
S3にjavaでアップロードとダウンロードメモ

#はじめに
javaからS3へのアップロード、ダウンロードのメモです。
proxy環境の場合は、proxy設定しないとタイムアウトになります。
それ以外は公式のサンプルで出来ました。

詳細は調査して、追記していきたいと思います。

#jarの導入(maven)
```maven:pom.xml
    <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-s3</artifactId>
            <version>1.11.112</version>
    </dependency>
```

#定数の宣言

```java:java
	static final String S3_ACCESS_KEY			= "";
	static final String S3_SECRET_KEY			= "";
	static final String S3_SERVICE_END_POINT	= "";
	static final String S3_REGION				= "";
	static final String S3_BUCKET_NAME			= "";
```


#認証処理

```java:java
    // 認証処理
    private static AmazonS3 auth(){
    	System.out.println("auth start");

    	// AWSの認証情報
    	AWSCredentials credentials = new BasicAWSCredentials(S3_ACCESS_KEY, S3_SECRET_KEY);

    	// クライアント設定
    	ClientConfiguration clientConfig = new ClientConfiguration();
    	clientConfig.setProxyHost("[proxyHost]");
    	clientConfig.setProxyPort([portNo]);

    	// エンドポイント設定
    	EndpointConfiguration endpointConfiguration = new EndpointConfiguration(S3_SERVICE_END_POINT,  S3_REGION);

    	// S3アクセスクライアントの生成
    	AmazonS3 client = AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(credentials))
    			.withClientConfiguration(clientConfig)
    			.withEndpointConfiguration(endpointConfiguration).build();

    	System.out.println("auth end");
    	return client;
    }
```

#アップロード処理
```java:java
    // ｱｯﾌﾟﾛｰﾄﾞ処理
    private static void upload() throws Exception{
    	System.out.println("upload start");

        // 認証処理
    	AmazonS3 client = auth();

    	File file = new File("[アップロードファイルパス]");
    	FileInputStream fis = new FileInputStream(file);


    	ObjectMetadata om = new ObjectMetadata();
    	om.setContentLength(file.length());

    	final PutObjectRequest putRequest = new PutObjectRequest(S3_BUCKET_NAME, file.getName(), fis, om);

    	// 権限の設定
    	putRequest.setCannedAcl(CannedAccessControlList.PublicRead);

    	// アップロード
    	client.putObject(putRequest);

    	fis.close();

    	System.out.println("upload end");
    }
```

#ダウンロード処理
```java:java
    // ﾀﾞｳﾝﾛｰﾄﾞ処理
    private static void download() throws Exception{
    	System.out.println("download start");

        // 認証処理
    	AmazonS3 client = auth();

    	final GetObjectRequest getRequest = new GetObjectRequest(S3_BUCKET_NAME, "[ダウンロードファイル名");

    	S3Object object = client.getObject(getRequest);

    	FileOutputStream fos = new FileOutputStream(new File("[出力先パス]"));
    	IOUtils.copy(object.getObjectContent(), fos);

    	fos.close();

    	System.out.println("download end");
    }
```
ツクールMVにおけるアクターの取得 

ツクマテさんでの質問に回答する中で、アクター(Game_Actor)関連の質問が多かったので記事にまとめます。

#アクターの格納場所
ツクールMVのグローバル変数（\$～となっている変数）で、アクターに関連するものは主に以下の３つです。
ツクールMV全体での特徴として、実行中に書き換えることを想定された変数は\$game～・実行中も内容が変わらないものは\$data～という名前になっています。

| 変数名       |型（クラス）|データ内容 |格納順|
|:-------------|------|----------------|------|
| $dataActors|Object[]|ゲーム開始時のアクター|管理番号順（1スタート）|
| $gameActors|Game_Actors|ゲーム実行中のアクターのデータ|管理番号順（1スタート）|
| $gameParty|Game_Party|加入しているアクター|加入順（0スタート）|

##$dataActors
アクターの初期データが格納されています。
設定されたデータはActors.jsonに格納されています。
ツクールのエディタでアクターの設定を変更すると、ここが変更されます。
よく\$dataActorsを編集しようとしたり、\$dataActorsをGame_Actorだと勘違いしてメソッドを呼び出そうとしたりするのを見ますが、そもそもできません。
\$data～系の変数は全てObject型であり、メソッドを持ちません。

##$gameActors
Game_Actorsというクラスが格納されています。
ただし、このクラスには以下のactor()というメソッドしか存在せず、実質Game_Actorの配列のように使います。

```js:rpg_objects.js
Game_Actors.prototype.actor = function(actorId) {
    if ($dataActors[actorId]) {
        if (!this._data[actorId]) {
            this._data[actorId] = new Game_Actor(actorId);
        }
        return this._data[actorId];
    }
    return null;
};
```
このメソッドですが、特定の番号のアクターを取得する場合にアクターが作成されていなければ新規に作成するという処理だけです。
パーティから外しても一度生成されたアクターは削除されません。

##$gameParty
ゲーム実行中のパーティが格納されています。
パーティ以外に所持金やアイテムなども含まれており、プレイヤーのデータ全般を扱うクラスです。
パーティに加入しているメンバーを取得する場合、以下の方法で行います。
例えば名前を取得したいのであれば以下のようなコードです

```js:
var actor = $gameParty.members()[0];
if(actor){
  console.log(actor.name());
}
```
この場合、F8で開けるコンソール画面に名前が出力されます。
画面に出したければ$gameMessage.add(actor.name())にしてみましょう。
nameのあとにカッコが必要なことに注意しましょう。

#実際に試してみる
プロジェクトを初期データで作成し、アクターをすべて加入させた後、以下のイベントコマンドを実行してみましょう。

<pre><font color="black">◆</font><font color="red">変数の操作：#0001 = $dataActors[1].name</font>
<font color="black">◆</font><font color="red">変数の操作：#0002 = $gameActors.actor(1).name()</font>
<font color="black">◆</font><font color="red">変数の操作：#0003 = $gameParty.members()[0].name()</font>
<font color="black">◆</font><font color="indigo">文章：</font><font color="gray">なし, ウィンドウ, 下</font>
<font color="black">：</font><font color="white">文章</font><font color="indigo">：</font><font color="navy">dataActor \v[1]</font>
<font color="black">：</font><font color="white">文章</font><font color="indigo">：</font><font color="navy">gameActor \v[2]</font>
<font color="black">：</font><font color="white">文章</font><font color="indigo">：</font><font color="navy">gemaParty \v[3]</font></pre>

この場合、ハロルドと３回表示されると思います。
パーティを並び替えてみると、一番下のパーティメンバーの表示が変更されるのがわかると思います。
また、イベントコマンドでハロルドの名前を変えてみましょう。
そうすると、２番目のgameActorの表示が変わることがわかると思います。
また、どの場合も１番目のdataActorが変化しないことがわかります。

#逆引きしてみる
Game_Actorは取得できたけど、これがパーティの何番目なのか知りたいという場合もあると思います。
この場合、Game_Actorのindex()メソッドを使います。
また、$gameActorの何番目に格納されているかを取得したい場合、Game_ActorのactorId()メソッドを使います。
スキルのダメージ式に以下の記述をして、スキルを味方に使わせてみてください。
*a.actorId()\*100*
*a.index()\*100*
（分散度は0%にしてください）
後ろのキャラが使うほど大ダメージになります。

#まとめ

* 特定のアクターのデータを取得したい場合、$gameActors.actor(番号)で取得
* パーティの順番に応じて取りたいときは、$gameParty.members()[番号]で取得
* どの処理を行う場合でも、適当な変数に入れて有効な値かどうかをチェックする
sympy.prodよりsympy.Mulの方がかなり速い


### 追記

@matsulib 様より[コメント](http://qiita.com/HigashinoSola/items/7514035a5dbaadbc5762#comment-84c5a9c6da4f027361ae)いただきました．sympy.Mulはデフォルトでキャッシュが有効になっているから速いとのことです．

---
1以上100未満の整数100個をランダムに作ります．


```python
import numpy as np
nums = [int(i) for i in np.random.randint(1, 100, 100)] #numpy.int64をintにしておく
```

`nums`の積を計算するのに最も速いのはなにかというお題です．

## 標準のライブラリで

検索すると`reduce`を使うのがよくヒットします．


```python
from functools import reduce
from operator import mul
```


```python
%timeit reduce(lambda x, y: x*y, nums)
```

    11.7 µs ± 104 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)



```python
%timeit reduce(mul, nums)
```

    6.71 µs ± 60.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)


`operator.mul` を用いると速くなりました．

## numpy

よく分かりませんが，オーバーフローで正しく計算されませんでした．


```python
np.prod(nums)
```




    0



## sympy

本命です．`sum`の掛け算バージョンである`sympy.prod`があります．


```python
import sympy
```


```python
%timeit sympy.prod(nums)
```

    7.1 µs ± 50.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)


しかし，実は`sympy.Mul` の方が速いという結界に．


```python
%timeit sympy.Mul(*nums)
```

    2.96 µs ± 39.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)


`sypmy.prod`の存在理由とはいったい……

## 結論

`sympy.prod(nums)` より `sympy.Mul(*nums)` の方が2倍以上速い！
Git初心者にオススメのツール、サービス

GroGroPHPです！
お疲れ様です！

この記事では、バージョン管理システム *Git* に関する、
オススメのツール、サービスを紹介していきます。

当初はコマンド集を作ろうと思いましたが、
もはやGitを覚えるためにコマンドは必要ないと考え、
ツールやサービスの紹介のみに絞りました。


# オススメのツールやサービス


## SourceTree
https://ja.atlassian.com/software/sourcetree

無料で使える、Git初心者に超絶オススメなツールです。

IDEを利用していない場合や、
バージョン管理に慣れていない場合、こちらを利用すると良いです。
インターフェースが分かりやすく、Git理解につながります。

Gitで必要なことのほとんどは、クリックだけでできてしまうので、
コマンドは必要なくなります。


## [追記]GitUp

https://gitup.co

Mac向けのGit管理GUIツールです。
SourceTree推しだったのですが、以下の記事に書かれているように、SourceTreeには複雑な機能が多すぎます。

https://qiita.com/JotaroS/items/5042d2944cf0573f133e

その点GitUpはかなりシンプルに見えるので、初心者に優しいかもしれません。
これからこちらのツールも使っていきます。


## IntelliJ IDEA(PHPStorm)
https://www.jetbrains.com/idea/

開発者向け。
こちらは有料ですが、本当に優秀なIDE(統合開発環境)です。
無料トライアルもあります。

開発をIDEでやっているのなら、
バージョン管理もIDEでやってしまうのが非常に効率的でオススメです。
クリックだけでコミット、プッシュ、プルリクエスト作成などまでできるので、
コマンドは必要ありません。


## GitHub
https://github.com/

超絶オススメのWebサービスです。

こちらは基本的にリポジトリの管理とプルリクエストに特化して利用している方が多いと思います。
ただ、Web上だけでブランチの作成、編集、コミットなど、軽い修正はここで完結できます。

~~パブリックリポジトリなら無料で作ることができます。
会社で使うなら有料契約してプライベートリポジトリを利用しましょう。~~
2020年に全面無料化しています。
https://jp.techcrunch.com/2020/04/15/2020-04-14-github-is-now-free-for-all-teams/

GitHubを使わずとも、自社でサーバーを立てて管理する方法もありますが、
手間が掛かるのと、初心者にはハードルが高いため、オススメしません。



# SourceTreeの使い方

|リンク|サイト|最終更新|備考|
|:--|:--|:--|:--|
|[はじめてのSourceTree（使い方編）](http://qiita.com/naoki85/items/c7660d70347e9e70b201)|Qiita|2016年04月03日||

※非常に使いやすいツールなので、GitHubとの連携記事で一緒に紹介されているケースが多いです。
その他の記事は以下のGitHubの使い方をご確認ください。

# GitUpの使い方

|リンク|サイト|最終更新|備考|
|:--|:--|:--|:--|
|[[macOS向け] gitのクライアントはGitUpがいいぞ。](https://qiita.com/JotaroS/items/5042d2944cf0573f133e)|Qiita|2020年01月29日||


# IntelliJ IDEAの使い方

|リンク|サイト|最終更新|備考|
|:--|:--|:--|:--|
|[意外と知らないIntelliJ IDEAのGit管理機能いろいろ（´-`）](http://qiita.com/yoppe/items/fd03607d4d4f191d32dd)|Qiita|2015年11月19日|Gif画像で分かりやすく解説してあります。導入の解説は省かれています。|
|[IntelliJ IDEAとGitHubを連携するときの設定メモ](http://qiita.com/rubytomato@github/items/b2ca27712146ed6f1426)|Qiita|2015年09月17日||
|[IntelliJ IDEAでGitとGitHubを使用する方法](http://www.task-notes.com/entry/20160511/1462935600)|TASK NOTES|2016年05月11日||
|[IntelliJ IDEAの「git rebase -i」が素晴らしく使いやすい件](http://www.karakaram.com/intellij-git-rebase-i)|Qiita|2016年09月23日||

# GitHubの使い方

|リンク|サイト|最終更新|備考|
|:--|:--|:--|:--|
|[今さら聞けない！GitHubの使い方【超初心者向け】](https://techacademy.jp/magazine/6235)|TechAcademy|2017年04月02日|コマンド解説あり|
|[【GitHub超初心者入門】この前初めてGitHubを使い始めたエンジニア見習いが書くGitHubの使い方と実践～とりあえず一緒に動かしてみようぜ！～](http://qiita.com/nnahito/items/565f8755e70c51532459)|Qiita|2017年05月10日|コマンド解説あり|
|[GitHub 入門](http://qiita.com/ay3/items/8d758ebde41d256a32dc)|Qiita|2016年09月29日|コマンド解説あり|
|[世界一優しいGitHubの使い方入門講座](https://tech-camp.in/note/4938/)|テックノート|2017年09月05日|SourceTreeとの連携|
|[今日からはじめるGitHub 〜 初心者がGitをインストールして、プルリクできるようになるまでを解説](https://employment.en-japan.com/engineerhub/entry/2017/01/31/110000)|エンジニアHub|2017年01月31日|コマンド解説あり|
|[[GitHubの使い方：画像付き] GitHubデビューが意外と簡単だった！！環境を作ってプッシュするまでの流れ](http://tontotakumi.com/web-seisaku/github-debut/)|tontotakumi.com|2015年05月29日|SourceTreeとの連携|

# まとめ

3年間、Gitに触れてきて、
Gitは本当にすばらしいと感じています。

そして、コマンドは不要で、Git理解のためには遠回りだと考えます。
私自身、今ではほぼ100%GUIでGit管理しています。
皆さんもぜひここから始めてみましょう。

# 最後に

もしこの記事が少しでも「役に立った」「いいね」と思ったら
LGTM、ストック、フォローお待ちしています！
投稿を続ける活力になります！
SketchでBootstorapを利用したWEBサイトのデザインを作成する

![sketch_bootstrap_1.png](https://qiita-image-store.s3.amazonaws.com/0/141934/075b21d8-8568-5083-ab06-2da67f63cd86.png)

# 事前準備
- [Sketch](https://www.sketchapp.com/)をインストールしておく
- [Bootstrap 3 UI Kit](http://bootstrapuikit.com/)をダウンロードしておく

# bootstrap-3-guiを開く
[Bootstrap 3 UI Kit](http://bootstrapuikit.com/)からダウンロードした`bootstrap-3-gui-kit.zip`を解凍する
フォルダ内の`bootstrap-3-gui`をダブルクリックしてSketchを起動する

![sketch_bootstrap_3.png](https://qiita-image-store.s3.amazonaws.com/0/141934/0844ab02-cc4b-0a96-7cf3-9ca7e35c378d.png)


# Pageを追加する
Page1にはBootstrapのテンプレートが格納されているため、作業用のPageを追加する

![sketch_bootstrap_5.png](https://qiita-image-store.s3.amazonaws.com/0/141934/1967d53e-9c0a-1f2d-a42b-b924a09e743d.png)

![sketch_bootstrap_6.png](https://qiita-image-store.s3.amazonaws.com/0/141934/a08a601a-2623-83f5-b84f-c353b1d506d3.png)

# Artboardを作成する
作業用のPageにArtboardを作成する

![sketch_bootstrap_7.png](https://qiita-image-store.s3.amazonaws.com/0/141934/9cc5e809-57fb-9029-08b7-9d4cfb337871.png)

![sketch_bootstrap_8.png](https://qiita-image-store.s3.amazonaws.com/0/141934/7f9f74b0-3dbc-f72b-e179-b48ed43e520c.png)

![sketch_bootstrap_9.png](https://qiita-image-store.s3.amazonaws.com/0/141934/c50e3608-659b-d906-f355-b71223e0ef03.png)

# デザインを作成する
Page1のテンプレートを作業用Pageにコピー＆編集してWEBサイトのデザインを作成する

![sketch_bootstrap_10.png](https://qiita-image-store.s3.amazonaws.com/0/141934/58ae9205-a1ea-9d79-0da1-d01d63a3795d.png)
pythonの組み込み

SalomeとかFreeCADとかpythonを組み込んだソフトを色々見かけるところから考えるに、pythonを組み込むのは比較的易しいと思われる。

組み込まれ方をよく見ると、次の2つのパターンを両方やっていたりする。

・pythonのインタープリタを内部で呼び出し、コマンドリストを解釈させ、その実行結果を取り込む
・そのソフトの主要機能をpythonスクリプトから呼び出せるようにモジュールを提供する

SalomeもFreeCADもこの両方をやっている。
後者までやるならば、windows版のgnuplotのように、テキストベースを基本としてGUIはそれにかぶせるだけという選択肢もありなのだが、3Dデータの操作などのGUIじゃないと無理な機能がある時は、テキストベース100%には出来ない。

この様な実装方法があることを覚えておくと、ソフト開発において、労力の最小化と最大限の柔軟性を同時に得られるケースが出てきます。
iOS11でウィジェットの表示を増やす・減らす際にviewWillTransitionToSizeが呼ばれなくなった問題


iOS10まではウィジェットのサイズを変更する際(show more、show lessボタン)にviewWillTransitionToSize:withTransitionCoordinator:が呼ばれていたところがiOS11では呼ばれなくなった件についてメモします。
（書き方の問題もあるので今回のような件はあまりないと思いますが・・）



```Objective-C
if (activeDisplayMode == NCWidgetDisplayModeCompact) {
        //小さいデフォのサイズ
} else { //show more状態
        //拡げたサイズ
        bigSize += 0.1; //viewWillTransitionToSizeを呼ぶために+0.1する
        [self setPreferredContentSize:bigSize];
}
```

だいたいこのような実装。viewWillTransitionToSizeでサイズ変更をしたいのになぜか呼ばれなくなった。。
ただ、サイズをめっちゃ大きくしたりすると呼ばれる。

そこで0.1を0.2に変更をするとviewWillTransitionToSizeが呼ばれるようになりました。。。



```Objective-C
if (activeDisplayMode == NCWidgetDisplayModeCompact) {
        //小さいデフォのサイズ
} else { //show more状態
        //拡げたサイズ
        bigSize += 0.2; //0.1だと呼ばれなくなった。なぜ？?
        [self setPreferredContentSize:bigSize];
}
```



参考：
https://forums.developer.apple.com/thread/85732
日付のバリデーション

# 長年の課題
Railsには標準で日付のフォーマットのバリデーションがありません。
これまで正規表現でチェックしたりgemを使ったりjavascript側でやったりと色々と試行してきたのですが……
# 解決策
最終的にベターな方法としてDate.parseを使う方法に落ち着きました。
これなら"2017-9-1"や"2017/09/01"、はたまた"20170901"のようなフォーマットにもゆるく対応できます。JQueryカレンダー入力にも。

```ruby:model/concern/date_validator.rb
class DateValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    value = record.send("#{attribute}_before_type_cast")
    begin
      Date.parse value if value.present?
    rescue ArgumentError
      record.errors[attribute] << I18n.t('errors.messages.invalid')
    end
  end
end
```

```ruby:model/user.rb
...
validates :birthday, date: true # 誕生日
```

# まとめ
しかしメタプログラミングやら例外を使っているので、どうしてもバッドノウハウ感が拭いきれません。
HTML5の日付入力欄が普及してくれれば、こんなことはブラウザ側に任せてしまいたいですね。
Gitのコマンド(初心者向け)

これまでGitを触ったことがなく、Gitの操作を勉強しようと思いGit-itを使用してみたので、
その際に使用したコマンドをメモとして書きます。
Git-itは以下のページからダウンロード
https://nodeschool.io/index.html

#コマンド一覧
※コマンドの<>は入力不要

##Gitの設定
- バージョンの確認
`git --version`

- 名前の設定
`git config --global user.name "<任意のユーザ名>"`

- Eメールアドレスの設定
`git config --global user.email "<任意のメールアドレス(xxxxxx@xxx.xxx)>"`

- Gitリポジトリの作成
`git init`

##Gitの更新
- ファイルの変更確認/現在のブランチ確認
`git status`

- コミット対象ファイルの指定(個別)
`git add <ファイル名>`

- コミット対象ファイルの指定(全て)
`git add .`

- Gitリポジトリへ保存
`git commit -m "変更の説明文"`

- ファイルの変更内容の確認
`git diff`

##GitHubの設定
- GitHubユーザの設定
`git config --global user.username <GitHubのユーザ名>`

- GitとGitHubのリモート設定(追加)
`git remote add <※任意のリモートサーバ名> <GitHubのリポジトリのURL>`
※メインのリモートサーバにはoriginをつける慣習がある

- GitとGitHubのリモート設定(変更)
`git remote set-url <リモートサーバ名> <GitHubのリポジトリのURL>`

- リモートの設定を確認
`git remote -v`

##GitとGitHubの連携
- Gitの内容をGitHubに送信（Push）
`git push <リモートサーバ名> <Gitのブランチ名>`

- GitHubのリポジトリをローカルにクローン
`git clone <GitHubのリポジトリのURL>`

- GitHubの変更を取得(pull)
`git pull <リモートサーバ名> <ブランチ名>`
変更がない場合は「Already up-to-date」と表示される

- GitHubの変更を確認
`git fetch --dry-run`

##Gitのブランチ操作
- Gitのブランチの作成
`git branch <任意のブランチ名>`

- Gitのブランチの切り替え
`git checkout <ブランチ名>`

- Gitの現在のブランチのブランチ名の変更
`git branch -m <変更後のブランチ名>`

- Gitのブランチ一覧を表示
`git branch`

- Gitのブランチをマージする
`git merge <ブランチ名>`

- Gitのブランチを削除
`git branch -d <ブランチ名>`

- GitHubのブランチを削除
`git push <リモートサーバ名> --delete <ブランチ名`
Firebaseでアプリを開発するならClient Side Joinを前提にすること

# Firebaseでアプリを開発する

みなさん、癖のあるデータベースであるFirebaseにもそろそろ慣れてきた頃でしょうか。
私は、Cookpadに入って4ヶ月が経ちました。幸せなことにCookpadでもFirebaseを使ってアプリの開発を行っています。
勉強会でもFirebaseの発表を多く見かけるようになって、嬉しい限りですもっといろんな方にFirebaseの魅力を届けるため、新しい記事を書くことにしました。
※この記事では特にRealtime DatabaseのことをさしてFirebaseと呼んでいます。

## 開発の鉄板 クライアントサーバーモデル
クライアントサーバーモデルとは`クライアント`と`サーバー`に機能を分離したソフトウエアの総称です。
2017年現在、モバイルで動作するほとんどのアプリはクライアントサーバーモデルを採用し開発されたものと考えて間違いないでしょう。ところが、Firebaseの登場によってクライアントサーバーモデルに変革が起こっていると思っています。

この変革を`サーバーレスアーキテクチャ`の時代と呼ぶ方がいますが、私はFirebaseがもたらしたのは、さらに一歩先の革新だと考えています。サーバーレスアーキテクチャの立役者はAWSのLambdaと行っても過言じゃないでしょう。Lambdaの機能はシンプルですがとても強力で、あらゆる恩恵をアプリ開発に与えてくれました。
しかし、やはり大部分の開発をクライアントサーバーモデルから離れることができないのが現実です。

## Firebaseがアプリ開発にもたらした革新

私はFirebaseの革新を次のように考えています。開発するアプリによって差はありますが大半のアプリではFirebaseの恩恵を受けられるはずです。しかし、Firebaseには欠点があります。残念ながらFirebaseは万能ではありません。欠点を含めFirebaseがもたらした革新を説明していきます。

- RESTを廃した
- RDBを廃した
- Queryを廃した

### RESTを廃した
Firebaseで開発を行って、一番よかったことはここです。開発において一番のボトルネックはクライアントサーバーモデルであることです。現代においてREST APIの開発コストは高すぎます。

#### クライアントが行う開発
- 認証の開発
- 通信APIの開発
- データモデルの開発
- データマッピングの開発（Codableで少し楽になった）
- エラー処理

#### サーバーが行う開発
- 認証の開発
- エンドポイントの設置
- データベースの設置
- クエリー
- ビジネス要件の処理
- エラー処理

他にもあると思いますが、エンドポイントの数に比例して開発コストは増大して行きます。

### RDBを廃した
RDBは、そもそもデータベースの特性自体がモバイル開発にミスマッチです。ほとんどのエンジニアは慣例的にMySQLを使っているにすぎません。
データベースの特性を見直せばなぜミスマッチなのか理解できると思います。「？」となった方は[こちら](http://qiita.com/1amageek/items/b350ee5ef0c9b2406583)をどうぞ

### Queryを廃した
Queryに関しては、もう少し機能拡張が欲しいの正直なところですが、Queryを廃したことによって今までのアプリ開発には新しい概念を導入する気づきになりました。`Client Side Join`を開発に取り入れたことです。RDBでは当然のリレーションですが、Firebaseでは勝手が違い`JOIN`がありません。そこでFirebaseではデータ同士の関係性はクライアントで解決します。
`Client Side Join`は、開発速度にも大きな影響を与えています。ネストの深いJSONをサーバーから受けクライアントで扱えるようにマッピングしていましたが。その作業は無くなります。
Firebaseでは通信にWebSocketが使われているため、一般のAPIを書くよりシンプルにClient Side Joinを実現できます。

例えば以下のような書き方ができます。

``` Swift

// iOSでTableViewを書いた例
// データソースには、たくさんのデータが入っていたのが普通だったがデータソースにはデータのIDしか保持していない。
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.datasource?.count ?? 0
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell: TableViewCell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath) as! TableViewCell
    configure(cell, atIndexPath: indexPath)
    return cell
}

func configure(_ cell: TableViewCell, atIndexPath indexPath: IndexPath) {
    // ここに注目
    // cellのconfigureのタイミングで値を取得しています。
    cell.disposer = self.datasource?.observeObject(at: indexPath.item, block: { (user) in
        cell.imageView?.contentMode = .scaleAspectFill
        cell.textLabel?.text = user?.name
    })
}

```

詳しく見たい方はこちらへ　https://github.com/1amageek/Salada

サーバーサイドで今まで当たり前のようにJOINして取得して、クライアントで展開していたがもうそんなに頑張らなくていいんです。

## Firebaseができないこと

- Search機能がない
- インフラの細かいコントロールができない

### Search機能がない
上にも書いた通りFirebaseはQueryは非常に弱いです。
例えばタイムラインの機能を作ろうとする場合、フォローしたユーザーの投稿を表示するという仕様を考えるでしょう。しかしFirebaseでは特定のユーザーの投稿だけを取得しアプリで表示させることはできません。
私が作るシステムではQueryをElasticSearchに任せています。
RDBであってもElasticSearchは使うと思うのでそもそもRDBに求める機能とはもはやなに？

### インフラの細かいコントロールができない。
Googleについて行くしかないですね。でも世界一のインフラをもつGoogleがオートスケールしてくれるので問題ないでしょう。

さぁFirebaseで開発を始めましょう。
tarコマンド、gzipコマンドの使い方

linuxでの圧縮解凍は、ファイルの場合はgzip(またはbzip2)、ディレクトリの場合はtarを使うのでまとめておく。

# ファイルの場合
## 圧縮 : gzip

```:
$ ls -l
-rw-r--r--  1 hoge hoge   677972  6 26 17:06 file
$ gzip file
$ ls -l
-rw-r--r--  1 hoge hoge   186144  6 26 17:06 file.gz
```

gzipコマンドでファイルの圧縮ができる。[ファイル名].gzが作成され、サイズが小さくなっているのがわかる。


## 解凍 : gunzip
```:
$ ls -l
-rw-r--r--  1 hoge hoge   186144  6 26 17:06 file.gz
$ gunzip file.gz
$ ls -l
-rw-r--r--  1 hoge hoge   677972  6 26 17:06 file
```

`gunzip`コマンドで解凍できる。

# ディレクトリの場合
ディレクトリに対してgzipコマンドは**使えない**。tarコマンドを使用してディレクトリをアーカイブファイルにすることで、ディレクトリに対して圧縮・解凍を行うことができる。

## 圧縮 : tar czf
```
$　tar czf directory.tar.gz directory
```
各オプションについて

- c : アーカイブ作成
- f : アーカイブファイル名を指定する
- z : gzipでの圧縮を行う

tarとgzipを一緒に行っているだけなので、
以下のように分けて書くこともできる。

```
$ tar cf directory.tar directory
$ gzip directory.tar
```

## 解凍 : tar xzf
```
$　tar xzf directory.tar.gz
```
各オプションについて

- x : アーカイブの展開
- f : アーカイブファイル名を指定する
- z : gzipでの解凍を行う

こちらも、以下のように分けて書くこともできる。

```
$ gunzip directory.tar.gz
$ tar xf directory.tar
```
ちょっとずつ読むドメイン駆動設計 第一部 ドメインモデルを機能させる 第ニ章 コミニュケーションと言語の使い方2

# ユビキタス言語でない言語
## お互いに重なったところのみが理解できる
![ユビキタス言語.png](https://qiita-image-store.s3.amazonaws.com/0/150455/a9a2f731-3177-e7bf-a12a-4640db838690.png)

重なったところのみが理解できるが、それは重なっていないところの言葉が入り混じった会話のなかでのコミュニケーションとなるので、どこが重なっている言葉なのか発見しずらいですよね。

## 何が起きるか
- 重なっていないところについては、通訳が必要となる
- チームメンバーのうち数人は、なんとか両者の言語を理解できるようになる。しかし暗黙知、通訳も正確ではなく、情報の流れがボトルネックとなる
- 間接的なコミュニケーションが増える

このことが原因で、

- モデルの概念が混乱を起こす
- 破壊的なリファクタリングにつながる
- 同じ用語を別々の意味で使い始めるのに気が付かない
- ドメインについての最も鋭い表現に気が付かない

といったことが起きます。

> 通訳はコミュニケーションを鈍らせ、知識の噛み砕きを沈滞させる。しかも、これらの方言はどれも共通語になれない。(第一部 第二章より)

では、どうするか。
お互い重なったところを認識し、重なっていないところをコミュニケーションに使用しないように**努力する**しかないですね。
ここでユビキタス言語の登場ですが、また読み込んで記事にしたいと思います。

通訳が必要ないコミュニケーションへの努力が必要。
TERASOLUNA5.xのブランクプロジェクトからTilesを削除する方法

### 1. はじめに

Spring MVCのアプリケーションを作成する場合、[TERASOLUNA Server Framework for Java (5.x)](http://terasolunaorg.github.io/guideline/) を利用することがあります。
しかし、デフォルトではテンプレートエンジンの[Tiles](https://tiles.apache.org/) が有効になっています。Tilesを使うことがほとんどないため、毎回Tilesに関する設定、ファイルを削除していました。
今回はTERASOLUNA5.xのブランクプロジェクトからTilesを削除する方法について、個人的な備忘録として残したいと思います。

### 2. 修正内容
#### 2.1 Webプロジェクトのpom.xmlからTilesの依存関係を削除

`terasoluna-gfw-recommended-web-dependencies`を依存関係から削除（コメントアウト）します。

```xml
<!-- 
<dependency>
    <groupId>org.terasoluna.gfw</groupId>
    <artifactId>terasoluna-gfw-recommended-web-dependencies</artifactId>
    <type>pom</type>
</dependency>
-->
```

以下を見れば分かるかと思いますが、Tiles関連のライブラリしか定義されていません。
https://github.com/terasolunaorg/terasoluna-gfw/blob/master/terasoluna-gfw-dependencies/terasoluna-gfw-recommended-web-dependencies/pom.xml

#### 2.2 Tilesのテンプレートファイル削除

`/webプロジェクト/src/main/webapp/WEB-INF/views/layout`に格納されているファイルがTiles関連のファイルです。
Tilesを利用しない場合は不要となるので、layoutディレクトリ自体削除してしまいます。

#### 2.3 不要となるViewResolverの削除

`/webプロジェクト/src/main/resources/META-INF/spring/spring-mvc.xml`にViewResolverの定義があります。
ここからTilesのView関連を削除します。
不要となるのは`<mvc:tiles />` と `<mvc:tiles-configurer>`の定義です。

```xml
<!-- Settings View Resolver. -->
<mvc:view-resolvers>
    <mvc:bean-name />
    <!--
    <mvc:tiles />
    -->
    <mvc:jsp prefix="/WEB-INF/views/" />
</mvc:view-resolvers>

<!--
<mvc:tiles-configurer>
    <mvc:definitions location="/WEB-INF/tiles/tiles-definitions.xml" />
</mvc:tiles-configurer>
-->
```

これで`/WEB-INF/tiles/tiles-definitions.xml`も不要になるので、Tilesディレクトリ自体も削除してしまいましょう。

#### 2.4 （おまけ）web.xmlの機能でヘッダ、フッターを自動で付与

`/webプロジェクト/src/main/webapp/WEB-INF/web.xml`の修正することでヘッダ、フッターを自動で追加することが可能です。
`<include-prelude>` と `<include-coda>` でJSPの開始と終了に別のJSPをインクルードさせます。

```xml
<jsp-config>
    <jsp-property-group>
        <url-pattern>*.jsp</url-pattern>
        <el-ignored>false</el-ignored>
        <page-encoding>UTF-8</page-encoding>
        <scripting-invalid>false</scripting-invalid>
        <include-prelude>/WEB-INF/views/common/include.jsp</include-prelude>
        <include-prelude>/WEB-INF/views/common/header.jsp</include-prelude>
        <include-coda>/WEB-INF/views/common/footer.jsp</include-coda>
    </jsp-property-group>
</jsp-config>
```

`<jsp-property-group>`自体を複数定義することができます。
ですので、特定の画面グループにはヘッダ、フッター、メニューを表示するが、特定の画面グループにはこれらを表示しない、といった設定も可能です。
これらの内容はJSP単体でもTilesでもできますので、重要なのは設計方針だといえるでしょう。

### 3. さいごに
今回はTERASOLUNA5.xのブランクプロジェクトからTilesを削除する方法について説明しました。
MVCアプリケーションにとってViewの実装技術は重要かと思います。
さまざまな技術（ライブラリ）がたくさん出てきているので、Viewを手軽に実装できるものをプロジェクト特性に応じて、適切に選択できるようにしていきたいなと思いました。
Library > Bug: Init -> Open -> Close -> Init > モジュール'ntdll.dll'のアドレスXXXでアドレスXXXに対する読取り違反がおきました。

```txt:動作環境
C++ Builder XE4 (またはVisual Studio Community 2017)
と某ライブラリ
```

とあるライブラリを使うソフトを開発中にはまった。

### 用意されたAPI（一部)

- XXX_Init()
- XXX_Open()
- XXX_Close()
- LoadLibrary()
- UnloadLibrary()

### エラー発生条件

1. XXX_Init()
2. XXX_Open()
3. XXX_Close()
4. XXX_Init()

> モジュール'ntdll.dll'のアドレスXXXでアドレスXXXに対する読取り違反がおきました。

### エラーが起きない条件

1. XXX_Init()
2. XXX_Init()
3. XXX_Init()
...

以下でもエラーは発生しない。

1. XXX_Init()
1. XXX_Open()
1. XXX_Init()
1. XXX_Open()
...

XXX_Close()の処理で何か問題があるようだ。

## 対処

### 案1 XXX_Init()は一回だけ実行する

XXX_Init()を複数回実行しないように上位ソフトを作成する。

それでいいかどうかは上位ソフトの仕様による。

### 案2 XXX_Init()前にUnloadLibrary()をする

1. UnloadLibrary()
2. LoadLibrary()
3. XXX_Init()
4. XXX_Open()
5. XXX_Close()
1. UnloadLibrary()
2. LoadLibrary()
3. XXX_Init()
...

上記にてエラーが出ないことを確認した。
CircleCi 2.0 で docker-compose を利用して環境の構築・テスト

Friday I/O です。  
[株式会社ワムウ](http://wamw.jp/)では、毎週金曜日は 興味がある事柄に取り組み、その成果を何らかの形でアウトプットする日 としております。

# はじめに

弊社ではローカル開発環境の構築に `Docker`, `Docker Compose` を主に使用しています。  
最近他社の開発者の方と共同で開発を行う仕事が増えてきたので、Github とCircleCi を連携させて自動テストするようにしています。こうすることでテストが通ったコードだけ master へマージすることができるようになり、コード品質の担保につながります。

# これまでのCircleCIでのテスト

これまで 案件を進める流れで CircleCI を利用する場合、

* ローカルでDocker開発環境構築
* CircleCI マシンで疑似テスト環境構築

と `CircleCI のマシンでもまた環境構築するの？` と二度手間でしたが、
CircleCI 2.0 からジョブにDockerが使えるようになりました。
環境構築はDocker にまかせてCI側でビルド・テストできると便利だよねーということでやりました。

# アプリケーションの構成

|    項目   | 名称    | バージョン |
|:---------:|---------|------------|
| Language  | PHP     | 7.1        |
| Framework | Laravel | 5.4        |
| DB        | MySQL   | 5.7        |


こんな感じの構成でCircleCI上でビルド・テストします。
PHPと、MySQLは公式のDockerイメージを使用します。

# 結果

`.circleci/config.yml` の記述は以下のような記述で環境の構築・テストすることができました。簡単。

```yaml
---

version: 2
jobs:
  build:
    machine: true
    steps:
      - checkout
      - run:
          name: Build Docker Image
          command: docker-compose build
      - run:
          name: Run tests
          command: |
            docker-compose run app-servie-name /bin/bash -c '\
              cp .env.example .env && \
              composer install --no-interaction && \
              php artisan key:generate && \
              ./artisan migrate:refresh && \
              ./vendor/bin/phpunit -c phpunit.circle.xml'
```

何をやっているかポイントとなる部分を説明をすると

1. `machine: true` CircleCI のVMを指定しています。ここの指定でDockerのイメージを指定することも可能ですが、その場合 volume のマウントができないためCircleCI のVM内でDocker を立ち上げるようにしています。

2. `Run tests` 内の記述について
ここではテストをしたい、コマンドの返りが欲しいので
`docker-compose run {service-name} /bin/bash -c` でコンテナを起動します。  
以降の処理はLaravelのお話で、アプリケーションのセットアップ、テストまでをずらっと書いてます。

3. `phpunit.circle.xml` について
Laravel に `phpunit.xml` が存在するのでコピーをして作成したものです。  
xml内では、docker-compose.yml で指定しているDB名と同じDB名を記述する必要があります。  
MySQL公式のDocker イメージが、起動時にDBが存在しない場合に`MYSQL_DATABASE`環境変数の値でDBを作成するので、作成されたDBをテストDBとして利用するようにしました。

以下にサンプルファイルを用意したので参考までに  

https://github.com/takecore/sample-circleci-test-with-laravel

# 問題点

上記のCircleCIの設定だとDockerイメージのビルドに時間がかかるので
CircleCIが提供するキャッシュ機能について来週書きます。
全てのAIファイルをX-1a PDFに保存（子フォルダー内のAIファイルも）

### AIファイルの入ってるフォルダーを選択；そのフォルダー内全ての**.ai**ファイル(子フォルダー内のも)全てX-1aPDFに保存（同じ階層に）

```javascript:AI2X-1aPDF.jsx
#target "Illustrator"
var folderObj = Folder.selectDialog("Select a folder");
var all = [];
if (folderObj) {
    getAI(folderObj);
    var i = all.length;
    if (i) {
        while (i--) {
            var m = all[i].length;
            while (m--) {
                ai2pdf(all[i][m]);
            }
        }
    }
    alert("Completed");
} else {
    alert("Please select a folder");
}
//////////////////////////////////////////////////////////
function getAI(folderObj) {
    var aiList = folderObj.getFiles("*.ai");
    if (aiList) all.push(aiList);

    var fileList = folderObj.getFiles();
    var L = fileList.length;
    while (L--) {
        if (fileList[L].constructor.name === "Folder") getAI(new Folder(fileList[L].fullName));
    }
}
//////////////////////////////////////////////////////////
function ai2pdf(aiPath) {
    var fileObj = new File(aiPath);
    var doc = app.open(fileObj);
    if (fileObj.open()) {
        var fname = fileObj.name.slice(0, -3);　　　
        options = new PDFSaveOptions();　　　
        options.pDFPreset = "[PDF/X-1a:2001 (日本)]";　　　
        options.preserveEditability = false;　　　
        savefile = new File(fileObj.path + "/" + fname + ".pdf");　　　
        doc.saveAs(savefile, options);
    }
    doc.close(SaveOptions.DONOTSAVECHANGES);
}
```
Google Optimize（オプティマイズ）をGoogleタグマネージャー（GTM)から導入する手順メモ

Google Optimize（オプティマイズ）をテストで入れようとしたら、サイトにタグマネージャー（GTM)が入っていたのでメモ。

#参考ページ

Googleの公式ヘルプ（2017/08/29時点で英語）
https://support.google.com/360suite/optimize/answer/6314801?authuser=1
見つけた日本語になっているヘルプ
https://support.google.com/tagmanager/answer/7164339?hl=ja

以下手順はヘルプページから持ってきました。

#タグマネージャー設定

タグマネージャーにログインし、コンテナの中に入る。

###1. 「タグ」メニューをクリックして、「新規」ボタンをクリック
![タグマネージャー画面1](https://qiita-image-store.s3.amazonaws.com/0/40940/97bdcb1c-ad09-3c07-4e91-d89a9ee08fd7.png)


###2. 「名前のないタグ」のデフォルト名を「Optimize - www.example.com」 などのわかりやすいタイトルに変更します。
![タグマネージャー画面2](https://qiita-image-store.s3.amazonaws.com/0/40940/9ca75d35-4635-0727-4aaf-34f6312b8a99.png)


###3. 「タグの設定」をクリックして、タグタイプは「Google Optimize」をクリック
![タグマネージャー画面3](https://qiita-image-store.s3.amazonaws.com/0/40940/f39f7b76-43fe-feb6-1083-35177e65c176.png)


###4. GoogleアナリティクストラッキングIDと、OptimizeコンテナIDを入力
計測するGoogleアナリティクスと、Google OptimizeのIDをそれぞれの管理画面から調べて入れる。
![タグマネージャー画面4](https://qiita-image-store.s3.amazonaws.com/0/40940/c9596b01-794b-ace1-34f4-88ddd23ddc11.png)

###5. [その他の設定]をクリックし、設定するフィールドと詳細設定をGoogleアナリティクスタグと同じ値で設定します。
ここがちょっとわからなかったので、飛ばしました。


###6.そのまま[保存] をクリックして、トリガーを設定せずにタグを保存します。


###7.タグマネージャーのタグ一覧ページに戻り、既存のアナリティクス設定（今回計測で使用するもの）を開きます。


###8.[タグの設定] をクリックして編集し、[詳細設定] > [タグの順序付け] を開きます。
結構奥深く下の方にある。。。
![タグマネージャー画面8](https://qiita-image-store.s3.amazonaws.com/0/40940/32f10bdd-a4be-f424-4b36-2ab1833ef3fe.png)



###9.「XXXXXが発行する前にタグを配信」チェックボックスをオンにして、さっき作ったOptimizeのタグを「設定タグ」として選択します。
![タグマネージャー画面9](https://qiita-image-store.s3.amazonaws.com/0/40940/8884ad2b-6aed-d1b6-9265-50aefdb95ce3.png)


###10.上記までができたら、タグマネージャーのコンテナをプレビューして、問題なければ公開する
うまくいけば、サイトをプレビューした時に、「Optimize」の文字が出る。

##ページを非表示にするスニペットを追加...について
通常のアナリティクス計測タグからの導入方法にもある「ページを非表示にするスニペット」の追加は
タグマネージャーでも対応することが推奨されていますが、
必須では無いそうなので、テストである今回は割愛。

ヘルプページによると、タグマネージャーの場合は、
タグ非表示スニペットの中のIDは
OptimizeコンテナIDではなく、タグマネージャコンテナIDを入力するらしいです。
15分区切りで、次の時間を知りたいとき

## こういうのをやりたい

- 13:00 => 13:15
- 13:05 => 13:15
- 13:21 => 13:30
- 23:47 => 00:00 （次の日)

Active Support を使うとヨサソウ
(日、月、年を跨ぐときもこれでおっけーなはず)

```rb
require 'date'
require 'active_support'
require 'active_support/core_ext'

QUARTER_HOUR = 15

def quarter_hour_time(date: DateTime.now)
  date.beginning_of_hour + ((date.min / QUARTER_HOUR + 1) * QUARTER_HOUR).minutes
end

now = DateTime.now
puts now
puts quarter_hour_time(date: now)

nenmatsu = DateTime.new(2017, 12, 31, 23, 55)  
puts nenmatsu                            # => 2017-12-31T23:55:00+00:00
puts quarter_hour_time(date: nenmatsu)   # => 2018-01-01T00:00:00+00:00
```
Wikipediaから関連するキーワードを取得してきて配列にするSwiftコード

Wikipediaからキーワードを取得してきて、配列にするSwiftコードを記述しました。

```swift
import Foundation

class GetWordArrayFromWikipedia: NSObject , XMLParserDelegate{
    
    var endFlag = false
    var WordArray:Array<String> = []
    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
        
        if(elementName == "pl"){
            WordArray.append(attributeDict["title"]!)
        }
    }
    
    func getWordArrayFromStringJp(seedWord:String) -> Array<String>
    {
        WordArray = []
        
        let url = NSURL(string: "https://ja.wikipedia.org/w/api.php?format=xml&action=query&prop=links&titles=" + seedWord.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)! + "&&pllimit=1000")
        self.endFlag = true
        let task = URLSession.shared.dataTask(with: url! as URL, completionHandler: {data, response, error in
            let parser : XMLParser = XMLParser(data: data!)
            parser.delegate = self
            parser.parse()
            self.endFlag = false
        })
        
        task.resume()
        
        while self.endFlag == true{
            usleep(100)
        }
        
        
        
        return WordArray
    }
    
    func parserDidEndDocument(_ parser: XMLParser) {
        
    }

}
```

これを駆動するコードは以下の通り

```swift
        var obj = GetWordArrayFromWikipedia();
        var array = obj.getWordArrayFromStringJp(seedWord: "機械学習");
        print(array)
```
高速にJSXを書いていくTips

AtomにEmmetとlanguage-babelを導入しましょう。

[![https://gyazo.com/1bac8b5c282c0caaed641834a17b0ade](https://i.gyazo.com/1bac8b5c282c0caaed641834a17b0ade.gif)](https://gyazo.com/1bac8b5c282c0caaed641834a17b0ade)

展開をタブなどにマッピングできますが、自分はデフォルトの<C-e>キーマップで使っています。
お世話になっている人はスターを付けるのを忘れずに。

https://github.com/gandm/language-babel
https://github.com/emmetio/emmet-atom

個人的に多用するが、Flowtypeで補完し、Emmetで展開し、保存時にprettierでフォーマットするパターンです。

[![https://gyazo.com/dcea03a44f5b92c16987c76f6718a5a6](https://i.gyazo.com/dcea03a44f5b92c16987c76f6718a5a6.gif)](https://gyazo.com/dcea03a44f5b92c16987c76f6718a5a6)


何かあればTwitterまたはコメント欄で議論しましょう。

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="ja" dir="ltr">まさかemmetなしでJSX書いてる人がいるのか？ <a href="https://t.co/XnxnEgxWrC">pic.twitter.com/XnxnEgxWrC</a></p>&mdash; 無職.js (@akameco) <a href="https://twitter.com/akameco/status/903546525602594817">September 1, 2017</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-conversation="none" data-cards="hidden" data-partner="tweetdeck"><p lang="ja" dir="ltr">Flowtype補完→Emmetで展開→prettierで整理が一番使うパターン <a href="https://t.co/zLDBchizOO">pic.twitter.com/zLDBchizOO</a></p>&mdash; 無職.js (@akameco) <a href="https://twitter.com/akameco/status/903547405550931968">September 1, 2017</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
Pythonからpingで他のマシンの死活監視をするライブラリ

# Pythonコードで他のマシンへの疎通確認する方法について

　システム管理をしていると、他のマシンの死活監視をpingコマンドによって行いたいケースに出くわすことがあります。
　このような場合、Pythonで作られたシステムからpingコマンドを使う場合に、subprocessを使ってOSのpingコマンドを呼び出す方法が一般的かと思います。
　しかし、この場合、外部のコマンドを使うことになるため、外部の環境に依存したり、細かい制御が難しいという問題がありました。

　そのため、今回はPythonの中で完結するようにsocketによる死活監視のためのライブラリを作成したので紹介します。

# Pingsを使った死活監視

　[pings](https://github.com/satoshi03/pings)はPythonでpingを送信するためのライブラリです。
　上記の通り、pingに使われるICMPパケットをsubprocessコマンドを使わずに、socketを使って送る事ができます。

 **注意**： pingsはroot/adminユーザーで実行する必要があります。

## インストール

pip経由でインストールすることができます。

```
pip install pings
```

# 使い方

　対象の死活の状態を監視したい場合は、以下のようにします。※実行時は必ず**rootユーザ/adminユーザ**で動かすようにしてください。

- `Ping`オブジェクトを初期化
- `ping()`メソッドの引数に監視対象を指定
  - このメソッドは、対象にpingを飛ばし、戻り値として `response` オブジェクトを返す
  - このオブジェクトの`is_reached()`に疎通状態の結果が格納

 具体的には、以下のようなコードになります。

```.python
import pings

p = pings.Ping() # Pingオブジェクト作成
res = p.ping("google.com")  # googleを監視

if res.is_reached():
  # 監視対象への接続ができた
  do_something()
else:
  # 監視対象への接続ができなかった
  do_something()
```

　pingメソッドの返り値として得られる`response` オブジェクトを使うことでネットワークの状態などの監視に役立てることができます。

```
res = p.ping("google.com")
res.print_messages()  # メッセージが表示される
```

 実行結果の例：

```
PING google.com (172.217.27.174): 55 data bytes
47 bytes from 172.217.27.174: icmp_seq=0 ttl=49 time=32.333 ms
--- google.com ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max = 32.333/32.333/32.333 ms
```

## より細かい設定

### 複数の対象の死活監視をしたい

　複数台のマシンを死活監視する場合は以下のようにします。

```.python
import pings

# 死活監視のマシンのIPアドレス
hosts = ["192.168.0.1", "192.168.0.2", "192.168.0.3"]

p = pings.Ping()

# マシンのIPアドレスを一つずつ取り出してpingコマンドを実行
for h in hosts:
  res = p.ping(h)
  if not res.is_reached():
    # 接続ができなかった場合の処理
    do_something()
```

### pingを複数回飛ばしたい

　デフォルトの設定の場合、pingを飛ばす回数が1回のみとなるため、複数回送信したい場合は `times` オプションを使用します。

```.python
import pings

p = pings.Ping()
res = p.ping("google.com", times=3)  # googleを監視, ３回pingを飛ばす
res.print_messages()
```

 実行結果の例：

```
PING google.com (172.217.27.174): 55 data bytes
47 bytes from 172.217.27.174: icmp_seq=0 ttl=49 time=32.333 ms
--- google.com ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max = 32.333/32.333/32.333 ms
```

### 標準出力に結果を出力したい

　Pingクラスの初期化時に`quiet`オプションを`False`に指定することで、実行中に標準出力にpingの結果が表示されます。

```.python
import pings

p = pings.Ping(quiet=False)
res = p.ping("google.com")  # googleを監視
```

実行結果の例：

```
PING google.com (172.217.27.174): 55 data bytes
47 bytes from 172.217.27.174: icmp_seq=0 ttl=49 time=32.333 ms
--- google.com ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max = 32.333/32.333/32.333 ms
```

# おわりに

　まだテストが不十分のため、環境によっては動かなかったり、うまく処理されないなどの問題がある可能性があります。
　使われる場合は、そのことを認識していただいてから使用するようにしてください。

　問題やコメントがありましたら、コメント欄やGithubのissueに書いていただけたらと思います。

# 参考

http://edo.blog.jp/archives/1790336.html
requirements.txtは#でコメントアウトできる

AWSでElastic Beanstalk上で動作するWEB APIを開発する際、[微妙にバージョンが古いPython3.4を利用する必要があります](http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/create-deploy-python-container.html)。

そして今回、Python3.6ではきちんと動作するのに、3.4では細かくバージョン指定しなければ動作しないライブラリが存在するという事態に当たってしまいました。

そのため、```requirements.txt```に「なぜ最新のバージョンを使っていないのか」という情報をメモするためコメントアウトする方法を調べたところ、Python本体と同様```#```でOKでした。

```py
...
ply==3.8
# Python3.4では最新バージョンのインポートに失敗するため
protobuf==3.2.0rc2                                               
pyasn1==0.3.3
...
```

こちらの記載で見つけました。普段は```pip freeze > requirements.txt```で自動生成するのでコメント書く機会はそれほど無さそうですけど。

https://github.com/pypa/pip/issues/564

> A line beginning with # is treated as a comment and ignored, so you can just place your comment on the line above instead of on the same line.

これで今回の記事の主題は終わりなのですが、「3.4では細かくバージョン指定しなければ動作しない」という挙動自体は納得できないので、ひとまず動作できる状態になったら調べてみようと思います。

具体的には、Python3.4で[```protobuf```ライブラリ](https://pypi.python.org/pypi/protobuf)の3.4.0のインポートにエラーが出てしまうため、3.2.0rc2を利用する必要がありました（その前後のバージョンでもダメでした）。

```python
  File "/home/ninomiyt/eb-virt/local/lib/python3.4/site-packages/google/cloud/client.py", line 26, in <module>
    from google.cloud._helpers import _determine_default_project
  File "/home/ninomiyt/eb-virt/local/lib/python3.4/site-packages/google/cloud/_helpers.py", line 33, in <module>
    from google.protobuf import duration_pb2
ImportError: No module named 'google.protobuf'
```

本来ならエラーの原因を特定してプルリク送る（もしくはissueをあげる）後に記事にできるとかっこいいんでしょうけど、リリースして仕事を終わらせるほうをひとまずは優先します。
[AWS]S3のバケットをまとめて削除する

# はじめに
AWSを使ってインターンの運営をしているのですが、インターンに参加している人全員のS3バケットがどんどん溜まってしまいます。そんな時やっぱ掃除しなきゃダメだよねという話になり、S3のバケットを一気に削除するスクリプトを書いてみました。

# 方法
AWS SDKをnodejsで実行することによって実装します。動作環境は以下になります。

- MacOS Sierra 10.12.4
- Node.js v6.10.2

# S3について

## 概要
念のためS3について説明しますが、簡単にいうとAWS上にいろんなファイルをおけるストレージサービスです。HTMLファイルなどを置いて静的ウェブホスティングというものをすることによって、静的なウェブサイトを作成することも可能です。
ちなみになぜS3というかというとSimple Storage Serviceの略だからだそうです。試したい方は以下のURLから。
[Amazon S3](https://aws.amazon.com/jp/s3/)

## バケット
S3にはストレージの単位としてバケットというものが用意されています。インターンでは、一人一人のバケットを作成することによって、個人のフロントエンドのアプリケーションを実現していました。

## オブジェクト
バケットの中にあるファイルをS3ではObjectと表現します。例えば、index.htmlというファイルとかも全てObjectとなるわけです。そしてこのオブジェクトにはKeyというものが付与されています。Keyは実際にはバケットのルートディレクトリからの絶対パスになります。 

# 削除方法
次の手順で実装します。
S3の仕様上、中身が入っているバケットは中身のファイルを全て削除した状態でないと削除できないので、中身を削除してからバケットを削除します。

1. 削除したくないバケット名の配列を定義する
1. AWSアカウントのS3の全てのバケットを取得する
1. 削除するバケットに入っているファイルのKeyを取得する
1. 3で取得したKeyを元にObjectを削除する
1. バケット自体を削除する

# 下準備

AWSアカウントのクレデンシャル情報を`aws configure`で設定してください。
詳しくは割愛します。

# ソースコード(スクリプト)

```s3-delete.js
const AWS = require('aws-sdk');
const s3 = new AWS.S3({region: 'ap-northeast-1'});  //各自指定
const MAX_KEY_SIZE = 1000;
//除外するバケット名を記述
const excludeTables = [
  "hoge",
  "fuga"
];

//Objectを削除するPromiseオブジェクト
var deleteObject = function(bucketName, key) {
  return new Promise((resolve, reject) => {
    s3.deleteObject({  //Objectを削除
      Bucket: bucketName,
      Key: key
    })
    .promise()
    .then((data) => {
      console.log("  [Key]" + key + " DELETED");
      resolve();
    })
    .catch((err) => {
      reject("  [Error]" + key + " NOT DELETED ¥n" + err);
    });
  });
}

s3.listBuckets({})  //Bucketの一覧を取得
.promise()
.then((data) => {
  let buckets = data.Buckets;
  buckets.filter((bucket) => {
    return (bucket.Name && excludeTables.indexOf(bucket.Name) == -1);
  })
  .map((bucket) => {
    s3.listObjects({Bucket: bucket.Name, MaxKeys: MAX_KEY_SIZE})  //Objectの一覧を取得
    .promise()
    .then((object) => {
      Promise.all(object.Contents.map((content) => {
        return deleteObject(object.Name, content.Key);
      }))
      .then(() => {
        s3.deleteBucket({  //Bucketの削除
          Bucket: object.Name
        })
        .promise()
        .then(() => {
          console.log("[Bucket] " + object.Name + "  DELETED");
        });
      })
      .catch((err) => {
        console.log(err);
      });
    })
    .catch((err) => {
      console.log(err);
    });
  })
})
.catch((err)=>{
  console.log(err);
});

```

# 実行方法
`npm install`してからスクリプトをnode.jsで実行します。

```
$ npm install
$ node s3-delete.js
```

# まとめ

Dynamoのテーブルの削除と同様に簡単にできるのかと思いきや、バケット自体を空にしなくてはいけないっていうのがちょっと面倒でした。これで、今後のインターン運営が楽になりそうです。
PhpStormからFTPSによるファイル転送ができない

#FTPSによるファイル転送ができない

Phpstormの、
**File>Settings>Deployment** で正しく設定を行っているはずなのに、
以下のエラーが出てファイルをサーバにアップロードできないことがあった。

```
Failed to transfer file 'C:\hoge_path': could not create FTP directory "ftps://hoge".
```

#原因

このとき通信プロトコルはFTPSを利用していたのだが、
PhpStormのFTPSクライアントはコントロールコネクションのSSLセッション再利用に対応できていないことが原因だった。

参考：[Connectionproblems with FTPS. "session reuse required" on vsFTPd 2.3.2](https://youtrack.jetbrains.com/issue/WI-18980)

#解決方法

この問題は **/etc/vsftpd/vsftpd.conf** の **require_ssl_reuse** を無効にすることで解決できる。しかし、セキュリティは多少下がる。

このrequire_ssl_reuseは、SSLセッション再利用をするかどうかを決める。

- require_ssl_reuse=NO：コントロールコネクションはSSL認証するけど、データコネクションはしない。データコネクション接続時に嘘が付ける。
- require_ssl_reuse=YES：コントロールコネクションでSSL認証して、データコネクションでもその合格した認証を接続に使う。接続先は正しい。

参考：[FTPの通信コネクションとSLLセッションの再利用について。](http://qiita.com/irucaice/items/7d798184270dc83b74b0)